ATLAS Offline Software
JetTrackMomentsTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
7 #include <sstream>
9 #include "xAODPFlow/PFO.h"
10 #include "xAODPFlow/FlowElement.h"
12 
14  : asg::AsgTool(name)
15 {
16 }
17 
18 
19 //**********************************************************************
20 
22 
23  ATH_MSG_INFO("Initializing JetTrackMomentsTool " << name());
24  if ( m_htsel.empty() ) {
25  ATH_MSG_INFO(" No track selector.");
26  } else {
27  ATH_MSG_INFO(" Track selector: " << m_htsel->name());
28  }
29 
30  if(m_jetContainerName.empty()){
31  ATH_MSG_ERROR("JetTrackMomentsTool needs to have its input container name configured!");
32  return StatusCode::FAILURE;
33  }
34 
35  // Set up the decoration names for each track pt cut
36  for (size_t iCut = 0; iCut < m_minTrackPt.size(); ++iCut) {
37  const float minPt = m_minTrackPt[iCut];
38  const std::string baseName = getMomentBaseName(minPt);
39  m_keysNumTrk.emplace_back( m_jetContainerName + ".NumTrk" + baseName + m_suffix);
40  m_keysSumPtTrk.emplace_back(m_jetContainerName + ".SumPtTrk" + baseName + m_suffix);
41  m_keysTrkWidth.emplace_back(m_jetContainerName + ".TrackWidth" + baseName + m_suffix);
42  if(m_doPFlowMoments){
43  m_keysNumCPFO.emplace_back( m_jetContainerName + ".NumChargedPFO" + baseName + m_suffix);
44  m_keysSumPtCPFO.emplace_back(m_jetContainerName + ".SumPtChargedPFO" + baseName + m_suffix);
45  m_keysCPFOWidth.emplace_back(m_jetContainerName + ".ChargedPFOWidth" + baseName + m_suffix);
46  }
47  }
48 
49  ATH_CHECK(m_vertexContainer_key.initialize());
51  ATH_CHECK(m_keysNumTrk.initialize());
52  ATH_CHECK(m_keysSumPtTrk.initialize());
53  ATH_CHECK(m_keysTrkWidth.initialize());
57 
58  return StatusCode::SUCCESS;
59 }
60 
61 //**********************************************************************
62 
63 
65 
66  // Get input vertex collection
67  auto handle_v = SG::makeHandle (m_vertexContainer_key);
68  if (!handle_v.isValid()){
69  ATH_MSG_ERROR("Could not retrieve the VertexContainer: "
70  << m_vertexContainer_key.key());
71  return StatusCode::FAILURE;
72  }
73 
74  const auto *vertexContainer = handle_v.cptr();
75 
76  // Get the track-vertex association
77  auto handle_tva = SG::makeHandle (m_tva_key);
78  if (!handle_tva.isValid()){
79  ATH_MSG_ERROR("Could not retrieve the TrackVertexAssociation: "
80  << m_tva_key.key());
81  return StatusCode::FAILURE;
82  }
83 
84  const auto *tva = handle_tva.cptr();
85 
86  for(const xAOD::Jet* jet : jets){
87  ATH_MSG_VERBOSE("On jet " << jet->index());
88 
89  // Retrieve the associated tracks.
90  std::vector<const xAOD::TrackParticle*> tracks;
91  bool havetracks = jet->getAssociatedObjects(m_assocTracksName, tracks);
92  if(!havetracks) ATH_MSG_WARNING("Associated tracks not found: " << m_assocTracksName);
93  ATH_MSG_VERBOSE("Successfully retrieved track particles for jet " << jet->index());
94 
95  std::vector<const xAOD::TrackParticle*> pflowTracks;
96  bool isPFlowJet = false;
97  if(m_doPFlowMoments) {
98  // Check if this is a PFlow jet. If so, get the PFO tracks.
99  xAOD::Type::ObjectType ctype = jet->rawConstituent(0)->type();
100  if (ctype == xAOD::Type::ParticleFlow) {
101  isPFlowJet = true;
102  size_t numConstit = jet->numConstituents();
103  for ( size_t i=0; i<numConstit; i++ ) {
104  const xAOD::PFO* constit = dynamic_cast<const xAOD::PFO*>(jet->rawConstituent(i));
105  if (constit->isCharged()){
106  const xAOD::TrackParticle *thisTrack = constit->track(0);//by construction xAOD::PFO can only have one track, in eflowRec usage
107  pflowTracks.push_back(thisTrack);
108  }// We have a charged PFO
109  }// Loop on jet constituents
110  }// This jet is either a PFlow jet (constituent type: xAOD::FlowElement::PFlow) or UFO jets
111  else if (ctype == xAOD::Type::FlowElement) {
112  isPFlowJet = true;
113  size_t numConstit = jet->numConstituents();
114  for ( size_t i=0; i<numConstit; i++ ) {
115  const xAOD::FlowElement* constit = dynamic_cast<const xAOD::FlowElement*>(jet->rawConstituent(i));
116  // UFO jet constituents have signalType xAOD::FlowElement::Charged or xAOD::FlowElement::Neutral
117  // PFlow jet constituents have signalType xAOD::FlowElement::ChargedPFlow or xAOD::FlowElement::NeutralPFlow
118  if(constit != nullptr && ((constit->signalType() & xAOD::FlowElement::PFlow) || constit->signalType() == xAOD::FlowElement::Charged)){
119  if (constit->isCharged()){
120  const xAOD::TrackParticle *thisTrack = dynamic_cast<const xAOD::TrackParticle*>(constit->chargedObject(0));//PFO should have only 1 track
121  if(thisTrack != nullptr) pflowTracks.push_back(thisTrack);
122  else ATH_MSG_WARNING("Charged PFO had no associated TrackParticle");
123  }// We have a charged PFO
124  }// The FlowElement is a PFO
125  }// Loop on jet constituents
126  }// This jet is made from xAOD::FlowElement, so we calculate the pflow moments if they're PFOs
127  }// We actually want to calculate the PFlow moments
128 
129  // For each track cut, compute and set the associated moments
130  for (size_t iCut = 0; iCut < m_minTrackPt.size(); ++iCut) {
134  // Get info
135  const float minPt = m_minTrackPt[iCut];
136  const std::vector<TrackMomentStruct> moments = getTrackMoments(*jet,vertexContainer,minPt,tracks,tva);
137  // Collate info
138  std::vector<int> numTrkVec; numTrkVec.resize(moments.size());
139  std::vector<float> sumPtTrkVec; sumPtTrkVec.resize(moments.size());
140  std::vector<float> trackWidthVec; trackWidthVec.resize(moments.size());
141  for ( size_t iVertex = 0; iVertex < moments.size(); ++iVertex ) {
142  numTrkVec[iVertex] = moments.at(iVertex).numTrk;
143  sumPtTrkVec[iVertex] = moments.at(iVertex).sumPtTrk;
144  trackWidthVec[iVertex] = moments.at(iVertex).trackWidth;
145  }
146  // Set moment decorations
147  numTrkHandle(*jet) = numTrkVec;
148  sumPtTrkHandle(*jet) = sumPtTrkVec;
149  trkWidthHandle(*jet) = trackWidthVec;
150 
151  if(m_doPFlowMoments) {
155  if(isPFlowJet){
156 
157  const std::vector<TrackMomentStruct> pflowMoments = getTrackMoments(*jet,vertexContainer,minPt,pflowTracks,tva);
158 
159  std::vector<int> pflowNumTrkVec; pflowNumTrkVec.resize(pflowMoments.size());
160  std::vector<float> pflowSumPtTrkVec; pflowSumPtTrkVec.resize(pflowMoments.size());
161  std::vector<float> pflowTrackWidthVec; pflowTrackWidthVec.resize(pflowMoments.size());
162  for ( size_t iVertex = 0; iVertex < pflowMoments.size(); ++iVertex ) {
163  pflowNumTrkVec[iVertex] = pflowMoments.at(iVertex).numTrk;
164  pflowSumPtTrkVec[iVertex] = pflowMoments.at(iVertex).sumPtTrk;
165  pflowTrackWidthVec[iVertex] = pflowMoments.at(iVertex).trackWidth;
166  }
167  // Set moment decorations
168  numCPFOHandle(*jet) = pflowNumTrkVec;
169  sumPtCPFOHandle(*jet) = pflowSumPtTrkVec;
170  cPFOWidthHandle(*jet) = pflowTrackWidthVec;
171  }
172  else{
173  // User configured for PFO track moments but this isn't a PFlow jet. Set them to empty vectors.
174  numCPFOHandle(*jet) = std::vector<int>();
175  sumPtCPFOHandle(*jet) = std::vector<float>();
176  cPFOWidthHandle(*jet) = std::vector<float>();
177  } // Should find a more graceful way to complain?
178  }// do PF moments
179  }
180  }
181 
182  return StatusCode::SUCCESS;
183 }
184 
185 
186 const std::vector<JetTrackMomentsTool::TrackMomentStruct> JetTrackMomentsTool::getTrackMoments(const xAOD::Jet& jet, const xAOD::VertexContainer* vertices, const float minTrackPt, const std::vector<const xAOD::TrackParticle*>& tracks, const jet::TrackVertexAssociation* tva) const
187 {
188  std::vector<TrackMomentStruct> moments;
189  moments.resize(vertices->size());
190 
191  for (size_t iVertex = 0; iVertex < vertices->size(); ++iVertex)
192  moments[iVertex] = getTrackMoments(jet,vertices->at(iVertex),minTrackPt,tracks,tva);
193 
194  return moments;
195 }
196 
197 JetTrackMomentsTool::TrackMomentStruct JetTrackMomentsTool::getTrackMoments(const xAOD::Jet& jet, const xAOD::Vertex* vertex, const float minTrackPt, const std::vector<const xAOD::TrackParticle*>& tracks, const jet::TrackVertexAssociation* tva) const
198 {
199  // Prepare the moments
200  TrackMomentStruct moments{};
201  moments.numTrk = 0;
202  moments.sumPtTrk = 0;
203  moments.trackWidth = 0;
204 
205  // Prepare const vars for jet eta/phi
206  const float jetEta = jet.eta();
207  const float jetPhi = jet.phi();
208 
209  // Track selection and counters
210  bool notsel = m_htsel.empty();
211  unsigned int nkeep = 0;
212  unsigned int nskip = 0;
213 
214  // Loop over the tracks
215  for (size_t iTrack = 0; iTrack < tracks.size(); ++iTrack)
216  {
217  const xAOD::TrackParticle* track = tracks.at(iTrack);
218  const float trackPt = track->pt();
219 
220  // Skip the track if it doesn't pass the cut
221  if (trackPt < minTrackPt)
222  continue;
223 
224  // Skip the track if it's not from the vertex in question
225  if( vertex == nullptr || vertex != tva->associatedVertex(track) ) continue ;
226 
227  // Check track passes track selection, otherwise mark as skipped
228  if ( notsel || m_htsel->accept(*track) ) {
229  ++nkeep;
230 
231  // Calculate necessary info for the moments
232  const double deltaR = xAOD::P4Helpers::deltaR(jetEta, jetPhi, track->eta(), track->phi() );
233 
234  // Adjust values as necessary for this track
235  moments.numTrk += 1;
236  moments.sumPtTrk += trackPt;
237  moments.trackWidth += deltaR * trackPt;
238  }
239  else { ++nskip;}
240  }
241 
242  // Finish processing the moments
243  moments.trackWidth = moments.sumPtTrk > 0 ? moments.trackWidth / moments.sumPtTrk : -1;
244 
245  ATH_MSG_DEBUG(" jet index= " << jet.index() << " pt="<<jet.pt()
246  << ": nsel=" << nkeep
247  << ", nrej=" << nskip << " minpt="<<minTrackPt);
248  return moments;
249 }
250 
251 const std::string JetTrackMomentsTool::getMomentBaseName(const float minTrackPt) const
252 {
253  int value = round(minTrackPt);
254  if (fabs(value - minTrackPt) > 0.1)
255  ATH_MSG_WARNING("Cut float and int disagree: " << minTrackPt << " float vs " << value << " int");
256 
257  std::ostringstream sout;
258  sout << "Pt" << value;
259  return sout.str();
260 }
261 
262 
xAOD::FlowElement_v1::Charged
@ Charged
Definition: FlowElement_v1.h:38
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
JetTrackMomentsTool::m_vertexContainer_key
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexContainer_key
Definition: JetTrackMomentsTool.h:67
JetTrackMomentsTool::m_htsel
ToolHandle< InDet::IInDetTrackSelectionTool > m_htsel
Definition: JetTrackMomentsTool.h:65
ObjectType
ObjectType
Definition: BaseObject.h:11
JetTrackMomentsTool::m_assocTracksName
Gaudi::Property< std::string > m_assocTracksName
Definition: JetTrackMomentsTool.h:60
xAODP4Helpers.h
xAOD::PFO_v1::track
const TrackParticle * track(unsigned int index) const
Retrieve a const pointer to a Rec::TrackParticle.
Definition: PFO_v1.cxx:691
MuonGM::round
float round(const float toRound, const unsigned int decimals)
Definition: Mdt.cxx:27
asg
Definition: DataHandleTestTool.h:28
JetTrackMomentsTool::TrackMomentStruct::numTrk
int numTrk
Definition: JetTrackMomentsTool.h:79
athena.value
value
Definition: athena.py:124
JetTrackMomentsTool.h
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
JetTrackMomentsTool::getMomentBaseName
const std::string getMomentBaseName(const float minTrackPt) const
Definition: JetTrackMomentsTool.cxx:251
JetTrackMomentsTool::m_suffix
Gaudi::Property< std::string > m_suffix
Definition: JetTrackMomentsTool.h:61
JetTrackMomentsTool::m_minTrackPt
Gaudi::Property< std::vector< float > > m_minTrackPt
Definition: JetTrackMomentsTool.h:62
JetTrackMomentsTool::m_keysTrkWidth
SG::WriteDecorHandleKeyArray< xAOD::JetContainer > m_keysTrkWidth
Definition: JetTrackMomentsTool.h:72
xAOD::FlowElement_v1::PFlow
@ PFlow
Definition: FlowElement_v1.h:45
SG::makeHandle
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition: ReadCondHandle.h:270
xAOD::FlowElement_v1::isCharged
bool isCharged() const
Definition: FlowElement_v1.cxx:56
PFO.h
jet
Definition: JetCalibTools_PlotJESFactors.cxx:23
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
FlowElement.h
JetTrackMomentsTool::decorate
virtual StatusCode decorate(const xAOD::JetContainer &jets) const override
Decorate a jet collection without otherwise modifying it.
Definition: JetTrackMomentsTool.cxx:64
lumiFormat.i
int i
Definition: lumiFormat.py:85
xAOD::P4Helpers::deltaR
double deltaR(double rapidity1, double phi1, double rapidity2, double phi2)
from bare bare rapidity,phi
Definition: xAODP4Helpers.h:150
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
jet::TrackVertexAssociation
Class to hold N-to-one aassociations between tracks and vertices.
Definition: TrackVertexAssociation.h:23
xAOD::FlowElement
FlowElement_v1 FlowElement
Definition of the current "pfo version".
Definition: FlowElement.h:16
SG::WriteDecorHandle
Handle class for adding a decoration to an object.
Definition: StoreGate/StoreGate/WriteDecorHandle.h:100
JetTrackMomentsTool::initialize
StatusCode initialize() override
Dummy implementation of the initialisation function.
Definition: JetTrackMomentsTool.cxx:21
xAOD::FlowElement_v1::signalType
signal_t signalType() const
JetTrackMomentsTool::m_jetContainerName
Gaudi::Property< std::string > m_jetContainerName
Definition: JetTrackMomentsTool.h:59
JetTrackMomentsTool::JetTrackMomentsTool
JetTrackMomentsTool(const std::string &name)
Definition: JetTrackMomentsTool.cxx:13
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
xAODType::ParticleFlow
@ ParticleFlow
The object is a particle-flow object.
Definition: ObjectType.h:41
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
JetTrackMomentsTool::m_keysNumCPFO
SG::WriteDecorHandleKeyArray< xAOD::JetContainer > m_keysNumCPFO
Definition: JetTrackMomentsTool.h:73
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
WriteDecorHandle.h
Handle class for adding a decoration to an object.
jet::TrackVertexAssociation::associatedVertex
const xAOD::Vertex * associatedVertex(const xAOD::TrackParticle *trk) const
Definition: TrackVertexAssociation.cxx:23
xAOD::PFO_v1::isCharged
bool isCharged() const
is a charged PFO
Definition: PFO_v1.cxx:251
TauGNNUtils::Variables::Track::trackPt
bool trackPt(const xAOD::TauJet &, const xAOD::TauTrack &track, double &out)
Definition: TauGNNUtils.cxx:472
JetTrackMomentsTool::getTrackMoments
const std::vector< TrackMomentStruct > getTrackMoments(const xAOD::Jet &jet, const xAOD::VertexContainer *vertices, const float minTrackPt, const std::vector< const xAOD::TrackParticle * > &tracks, const jet::TrackVertexAssociation *tva) const
Definition: JetTrackMomentsTool.cxx:186
xAOD::FlowElement_v1::chargedObject
const xAOD::IParticle * chargedObject(std::size_t i) const
Definition: FlowElement_v1.cxx:127
xAOD::PFO_v1
Class describing a particle flow object.
Definition: PFO_v1.h:35
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
JetTrackMomentsTool::m_keysSumPtTrk
SG::WriteDecorHandleKeyArray< xAOD::JetContainer > m_keysSumPtTrk
Definition: JetTrackMomentsTool.h:71
mc.nskip
nskip
Definition: mc.PhPy8EG_Hto4l_NNLOPS_nnlo_30_ggH125_ZZ4l.py:41
xAOD::Jet_v1
Class describing a jet.
Definition: Jet_v1.h:57
Trk::vertex
@ vertex
Definition: MeasurementType.h:21
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
JetTrackMomentsTool::m_doPFlowMoments
Gaudi::Property< bool > m_doPFlowMoments
Definition: JetTrackMomentsTool.h:63
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
JetTrackMomentsTool::m_tva_key
SG::ReadHandleKey< jet::TrackVertexAssociation > m_tva_key
Definition: JetTrackMomentsTool.h:68
defineDB.jets
list jets
Definition: JetTagCalibration/share/defineDB.py:24
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
DataVector::at
const T * at(size_type n) const
Access an element, as an rvalue.
JetTrackMomentsTool::m_keysNumTrk
SG::WriteDecorHandleKeyArray< xAOD::JetContainer > m_keysNumTrk
Definition: JetTrackMomentsTool.h:70
JetTrackMomentsTool::m_keysSumPtCPFO
SG::WriteDecorHandleKeyArray< xAOD::JetContainer > m_keysSumPtCPFO
Definition: JetTrackMomentsTool.h:74
makeComparison.deltaR
float deltaR
Definition: makeComparison.py:36
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
JetTrackMomentsTool::m_keysCPFOWidth
SG::WriteDecorHandleKeyArray< xAOD::JetContainer > m_keysCPFOWidth
Definition: JetTrackMomentsTool.h:75
JetTrackMomentsTool::TrackMomentStruct
Definition: JetTrackMomentsTool.h:79
xAOD::FlowElement_v1
A detector object made of other lower level object(s)
Definition: FlowElement_v1.h:25