ATLAS Offline Software
Loading...
Searching...
No Matches
TauVertexFinder.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#ifndef XAOD_ANALYSIS
6#include "TauVertexFinder.h"
7
8TauVertexFinder::TauVertexFinder(const std::string& name ) :
9 TauRecToolBase(name) {}
10
12
13
16
17 if( m_useTJVA) {
18 ATH_MSG_INFO("using TJVA to determine tau vertex");
20 ATH_CHECK( m_trkVertexAssocTool.retrieve() );
21 }
22
23 return StatusCode::SUCCESS;
24}
25
26
28 const EventContext& ctx) const
29{
30 const xAOD::VertexContainer* vertexContainer = nullptr;
31 return executeTool(pTau, ctx, vertexContainer);
32}
33
34
36 const EventContext& ctx,
37 const xAOD::VertexContainer* vertexContainer) const
38{
39 const xAOD::VertexContainer * vxContainer = nullptr;
40
41 if (!m_vertexInputContainer.empty()) {
43 if (!vertexInHandle.isValid()) {
44 ATH_MSG_ERROR ("Could not retrieve HiveDataObj with key " << vertexInHandle.key());
45 return StatusCode::FAILURE;
46 }
47 vxContainer = vertexInHandle.cptr();
48 }
49 else {
50 if (vertexContainer != nullptr) {
51 vxContainer = vertexContainer;
52 }
53 else {
54 ATH_MSG_WARNING ("No Vertex Container in trigger");
55 return StatusCode::FAILURE;
56 }
57 }
58
59 ATH_MSG_VERBOSE("size of VxPrimaryContainer is: " << vxContainer->size() );
60 if (vxContainer->empty()) return StatusCode::SUCCESS;
61
62 // find default PrimaryVertex (needed if TJVA is switched off or fails)
63 const xAOD::Vertex* primaryVertex = nullptr;
64 if (inTrigger()) { // trigger: find default PrimaryVertex (highest sum pt^2)
65 primaryVertex = (*vxContainer)[0];
66 }
67 else { // offline: the first and only primary vertex candidate is picked
68 for (const auto* vertex : *vxContainer) {
69 if (vertex->vertexType() == xAOD::VxType::PriVtx) {
70 primaryVertex = vertex;
71 break;
72 }
73 }
74 }
75
76 // associate vertex to tau
77 if (primaryVertex) pTau.setVertex(vxContainer, primaryVertex);
78
79 //stop here if TJVA is disabled
80 if (!m_useTJVA) return StatusCode::SUCCESS;
81
82 // additional protection in case TJVA is run online - not supported for Run3
83 if ( m_useTJVA && inTrigger()){
84 ATH_MSG_ERROR("TJVA not available for online");
85 return StatusCode::FAILURE;
86 }
87
88 // try to find new PV with TJVA
89 ATH_MSG_DEBUG("TJVA enabled -> try to find new PV for the tau candidate");
90
91 float maxJVF = -100.;
92 ElementLink<xAOD::VertexContainer> newPrimaryVertexLink = getPV_TJVA(pTau, *vxContainer, maxJVF );
93 if (newPrimaryVertexLink.isValid()) {
94 // set new primary vertex
95 // will overwrite default one which was set above
96 pTau.setVertexLink(newPrimaryVertexLink);
97 // save highest JVF value
98 pTau.setDetail(xAOD::TauJetParameters::TauJetVtxFraction,static_cast<float>(maxJVF));
99 ATH_MSG_DEBUG("TJVA vertex found and set");
100 }
101 else {
102 ATH_MSG_WARNING("couldn't find new PV for TJVA");
103 }
104
105 return StatusCode::SUCCESS;
106}
107
108
111 const xAOD::VertexContainer& vertices,
112 float& maxJVF) const
113{
114 const xAOD::Jet* pJetSeed = pTau.jet();
115 std::vector<const xAOD::TrackParticle*> tracksForTJVA;
116
117 // the implementation follows closely the example given in modifyJet(...) in JetVertexFractionTool
118
119 std::vector<const xAOD::TrackParticle*> assocTracks;
120 if (! pJetSeed->getAssociatedObjects(m_assocTracksName, assocTracks)) {
121 ATH_MSG_ERROR("Could not retrieve the AssociatedObjects named \""<< m_assocTracksName <<"\" from jet");
123 }
124
125 // Store tracks that meet TJVA track selection criteria and are between deltaR of 0.2 with the jet seed
126 // To be included in the TJVA calculation
127 // Maybe not as efficient as deleting unwanted tracks from assocTrack but quicker and safer for now.
128 float sumTrackAll = 0.0;
129 for ( auto xTrack : assocTracks ) {
130 if ( (xTrack->p4().DeltaR(pJetSeed->p4())<m_dDeltaRMax) && m_TrackSelectionToolForTJVA->accept(*xTrack) ) {
131 if (!inEleRM()) {
132 tracksForTJVA.push_back(xTrack);
133 }
134 else {
135 static const SG::ConstAccessor<ElementLink<xAOD::TrackParticleContainer>> acc_originalTrack("ERMOriginalTrack");
136 if (!acc_originalTrack.isAvailable(*xTrack)) {
137 ATH_MSG_WARNING("Original ERM track link is not available, skipping track");
138 continue;
139 }
140 auto original_id_track_link = acc_originalTrack(*xTrack);
141 if (!original_id_track_link.isValid()) {
142 ATH_MSG_WARNING("Original ERM track link is not valid, skipping track");
143 continue;
144 }
145 tracksForTJVA.push_back(*original_id_track_link);
146 }
147 sumTrackAll += xTrack->pt();
148 }
149 }
150
151 if (this->msgLevel() <= MSG::DEBUG){
152 ATH_MSG_DEBUG("tracksForTJVA # = " << tracksForTJVA.size() << ", sum pT = " << sumTrackAll);
153
154 for (uint i = 0; i < tracksForTJVA.size(); i++){
155 ATH_MSG_DEBUG("tracksForTJVA[" << i << "].pt = " << tracksForTJVA[i]->pt());
156 }
157 }
158
160
161 // Get track vertex map
162 std::vector<const xAOD::Vertex*> vertVec;
163 for (const xAOD::Vertex* vert : vertices) {
164 vertVec.push_back(vert);
165 }
166
167 if (this->msgLevel() <= MSG::DEBUG){
168 ATH_MSG_DEBUG("Vertex # = " << vertVec.size());
169 for (uint i = 0; i < vertVec.size(); i++){
170 ATH_MSG_DEBUG("vertVec[" << i << "].z = " << vertVec[i]->z());
171 }
172 }
173
174 // Tool returns map between vertex and tracks associated to that vertex (based on selection criteria set in config)
175 trktovxmap = m_trkVertexAssocTool->getMatchMap(tracksForTJVA, vertVec);
176
177 if (this->msgLevel() <= MSG::DEBUG){
178 for (const auto& [vtx, trks] : trktovxmap){
179 std::stringstream ss;
180 for (auto ass_trk : trks){
181 for (uint i=0; i < tracksForTJVA.size(); i++){
182 if (ass_trk->p4() == tracksForTJVA[i]->p4()) {
183 ss << i << ", ";
184 break;
185 }
186 }
187 }
188 ATH_MSG_DEBUG("Vtx[" << vtx->index() << "] associated with trks [" << ss.str() << "]");
189 }
190 }
191
192 // Get the highest JVF vertex and store maxJVF for later use
193 // Note: the official JetMomentTools/JetVertexFractionTool doesn't provide any possibility to access the JVF value, but just the vertex.
194 maxJVF=-100.;
195 // Store sum(deltaz(track-vertex)) and jet vertex fraction scores
196 std::vector<float> sumDz;
197 std::vector<float> v_jvf;
198 size_t maxIndex = 0;
199 for (const xAOD::Vertex* vert : vertices) {
200 float jvf = 0.0;
201 std::vector<const xAOD::TrackParticle*> tracks = trktovxmap[vert];
202 // get jet vertex fraction and sumdeltaZ scores
203 std::pair<float, float> spair = getVertexScores(tracks, vert->z());
204 jvf = (sumTrackAll!=0. ? spair.first/sumTrackAll : 0.);
205 v_jvf.push_back(jvf);
206 sumDz.push_back(spair.second);
207
208 if (jvf > maxJVF) {
209 maxJVF = jvf;
210 maxIndex = vert->index();
211 }
212 }
213
214 ATH_MSG_DEBUG("First TJVA");
215 ATH_MSG_DEBUG("TJVA vtx found at z: " << vertices.at(maxIndex)->z() << " i_vtx = " << maxIndex << "jvf = " << maxJVF);
216 ATH_MSG_DEBUG("highest pt vtx found at z (i=0): " << vertices.at(0)->z());
217
218 float min_sumDz = 99999999.;
219 for (const xAOD::Vertex* vert : vertices) {
220 ATH_MSG_DEBUG("i_vtx=" << vert->index() << ", z=" << vert->z() << ", JVF=" << v_jvf[vert->index()] << ", sumDz=" << sumDz[vert->index()]);
221 if ( v_jvf[vert->index()] == maxJVF ){
222 // in case of 0 tracks, first vertex will have sumDz=0, and be selected
223 if (sumDz[vert->index()] < min_sumDz){
224 min_sumDz = sumDz[vert->index()];
225 maxIndex = vert->index();
226 }
227 }
228 }
229
230
231 ATH_MSG_DEBUG("Final TJVA");
232 ATH_MSG_DEBUG("TJVA vtx found at z: " << vertices.at(maxIndex)->z() << " i_vtx = " << maxIndex);
233
234 return ElementLink<xAOD::VertexContainer> (vertices, maxIndex);
235}
236
237// get sum of pT from tracks associated to vertex (tracks from track to vertex map) (pair first)
238// sum over tracks associated to vertex of deltaZ(track-vertex) (pair second)
239std::pair<float,float> TauVertexFinder::getVertexScores(const std::vector<const xAOD::TrackParticle*>& tracks, float vx_z) const{
240
241 float sumTrackPV = 0.;
242 float sumDeltaZ = 0.;
243 for (const auto* trk : tracks){
244 sumTrackPV += trk->pt();
245 sumDeltaZ += std::abs(trk->z0() - vx_z + trk->vz());
246 }
247
248 return std::make_pair(sumTrackPV, sumDeltaZ);
249}
250#endif
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
unsigned int uint
static Double_t ss
#define z
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.
bool empty() const noexcept
Returns true if the collection is empty.
Helper class to provide constant type-safe access to aux data.
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
virtual const std::string & key() const override final
Return the StoreGate ID for the referenced object.
TauRecToolBase(const std::string &name)
bool inEleRM() const
bool inTrigger() const
ElementLink< xAOD::VertexContainer > getPV_TJVA(const xAOD::TauJet &tauJet, const xAOD::VertexContainer &vertices, float &maxJVF) const
TauVertexFinder(const std::string &name)
Constructor and Destructor.
StatusCode executeTool(xAOD::TauJet &pTau, const EventContext &ctx) const override
Execute - called for each tau candidate.
StatusCode initialize() override
Tool functions.
std::pair< float, float > getVertexScores(const std::vector< const xAOD::TrackParticle * > &tracks, float vx_z) const
ToolHandle< CP::ITrackVertexAssociationTool > m_trkVertexAssocTool
Gaudi::Property< std::string > m_assocTracksName
Gaudi::Property< double > m_dDeltaRMax
Gaudi::Property< bool > m_useTJVA
ToolHandle< InDet::IInDetTrackSelectionTool > m_TrackSelectionToolForTJVA
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexInputContainer
virtual FourMom_t p4() const
The full 4-momentum of the particle.
Definition Jet_v1.cxx:71
std::vector< const T * > getAssociatedObjects(const std::string &name) const
get associated objects as a vector<object> this compact form throws an exception if the object is not...
void setVertexLink(const VertexLink_t &vertexLink)
void setDetail(TauJetParameters::Detail detail, int value)
void setVertex(const xAOD::VertexContainer *cont, const xAOD::Vertex *vertex)
const Jet * jet() const
float z() const
Returns the z position.
@ TauJetVtxFraction
@Tau Jet Vertex Fraction
Definition TauDefs.h:262
@ PriVtx
Primary vertex.
Jet_v1 Jet
Definition of the current "jet version".
std::map< const xAOD::Vertex *, xAOD::TrackVertexAssociationList > TrackVertexAssociationMap
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Vertex_v1 Vertex
Define the latest version of the vertex class.
TauJet_v3 TauJet
Definition of the current "tau version".
Definition TauJet.h:17