ATLAS Offline Software
Loading...
Searching...
No Matches
VertexFittingTool.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
6// Local
9
10// Athena
12
13// C/C++
14#include <cmath>
15#include <iostream>
16#include <sstream>
17
18using namespace std;
19
20//=============================================================================
22 const std::string& t, const std::string &name, const IInterface* p
23): AthAlgTool(t, name, p)
24{
25 declareInterface<Prompt::IVertexFittingTool>(this);
26}
27
28//=============================================================================
30{
31 ATH_CHECK(m_vertexFitter.retrieve());
32
34 ATH_CHECK(m_seedVertexFitter.retrieve());
35 }
36
37 m_distToPriVtx = std::make_unique<SG::AuxElement::Decorator<float> > (m_distToPriVtxName);
38 m_normDistToPriVtx = std::make_unique<SG::AuxElement::Decorator<float> > (m_normDistToPriVtxName);
39 m_distToRefittedPriVtx = std::make_unique<SG::AuxElement::Decorator<float> > (m_distToRefittedPriVtxName);
40 m_normDistToRefittedPriVtx = std::make_unique<SG::AuxElement::Decorator<float> > (m_normDistToRefittedPriVtxName);
41 m_distToRefittedRmLepPriVtx = std::make_unique<SG::AuxElement::Decorator<float> > (m_distToRefittedRmLepPriVtxName);
42 m_normDistToRefittedRmLepPriVtx = std::make_unique<SG::AuxElement::Decorator<float> > (m_normDistToRefittedRmLepPriVtxName);
43
44 m_timer.Reset();
45
46 ATH_MSG_DEBUG("VertexFittingSvc::initialize - doSeedVertexFit = " << m_doSeedVertexFit);
47 ATH_MSG_DEBUG("VertexFittingSvc::initialize - vertexFitter = " << m_vertexFitter.name());
48
49 return StatusCode::SUCCESS;
50}
51
52//=============================================================================
54{
55 //
56 // Delete pointers
57 //
58 m_timer.Stop();
59
60 ATH_MSG_INFO("VertexFittingSvc::finalize - number of total fits: " << m_countNumberOfFits);
61 ATH_MSG_INFO("VertexFittingSvc::finalize - number of failed fits: " << m_countNumberOfFitsFailed);
62 ATH_MSG_INFO("VertexFittingSvc::finalize - number of invalid vtxs: " << m_countNumberOfFitsInvalid);
63 ATH_MSG_INFO("VertexFittingSvc::finalize - fitting timer: " << PrintResetStopWatch(m_timer));
64
65 return StatusCode::SUCCESS;
66}
67
68//=============================================================================
70 const EventContext& ctx,
71 const FittingInput &input,
72 const std::vector<const xAOD::TrackParticle* > &tracks,
73 VtxType vtxType
74)
75{
76 //
77 // Make new secondary vertex
78 //
81
82 if(!input.priVtx) {
83 ATH_MSG_WARNING("fitVertexWithPrimarySeed -- missing primary vertex");
84 return nullptr;
85 }
86
87 // Fit a new secondary vertex
88 std::unique_ptr<xAOD::Vertex> secondaryVtx = getSecondaryVertexWithSeed(
89 ctx, tracks, input.inDetTracks, input.priVtx->position()
90 );
91
92 if(!secondaryVtx) {
94 ATH_MSG_WARNING("fitVertexWithPrimarySeed -- failed to fit vertex");
95 return nullptr;
96 }
97
98 if(!isValidVertex(secondaryVtx.get())) {
100
101 ATH_MSG_WARNING("fitVertexWithPrimarySeed -- failed to get valid vertex");
102 return nullptr;
103 }
104
106
107 // Decorate the newly created vertex
108 static const SG::AuxElement::Accessor<int> indexAcc("SecondaryVertexIndex");
109 static const SG::AuxElement::Accessor<int> typeAcc("SVType");
110
111 indexAcc(*secondaryVtx) = m_secondaryVertexIndex;
112 typeAcc(*secondaryVtx) = static_cast<int>(vtxType);
113
114 decorateNewSecondaryVertex(input, secondaryVtx.get());
115
116 return secondaryVtx;
117}
118
119//=============================================================================
121 const EventContext& ctx,
122 const FittingInput &input,
123 const std::vector<const xAOD::TrackParticle* > &tracks,
124 const Amg::Vector3D& seed,
125 VtxType vtxType
126)
127{
128 //
129 // Make new secondary vertex
130 //
133
134 std::unique_ptr<xAOD::Vertex> secondaryVtx = getSecondaryVertexWithSeed(
135 ctx, tracks, input.inDetTracks, seed
136 );
137
138 if(!secondaryVtx) {
140
141 ATH_MSG_WARNING("fitVertexWithSeed -- failed to fit vertex");
142 return nullptr;
143 }
144
145 if(!isValidVertex(secondaryVtx.get())) {
147
148 ATH_MSG_WARNING("fitVertexWithSeed -- failed to get valid vertex");
149 return nullptr;
150 }
151
153
154 // Decorate the newly created vertex
155 static const SG::AuxElement::Accessor<int> indexAcc("SecondaryVertexIndex");
156 static const SG::AuxElement::Accessor<int> typeAcc("SVType");
157
158 indexAcc(*secondaryVtx) = m_secondaryVertexIndex;
159 typeAcc(*secondaryVtx) = static_cast<int>(vtxType);
160
161 decorateNewSecondaryVertex(input, secondaryVtx.get());
162
163 return secondaryVtx;
164}
165
166//=============================================================================
168{
169 //
170 // Check if vertex is valid
171 //
172 bool bad_vtx = false;
173
174 if(!vtx){
175 ATH_MSG_WARNING("VertexFittingSvc::Validate_Vertex -- invalid vtx pointer!!!");
176 return false;
177 }
178
179 if(vtx->covariance().empty()) {
180 bad_vtx = true;
181 ATH_MSG_WARNING("VertexFittingSvc::Validate_Vertex -- empty vtx covariance!!!");
182 }
183
184 float chisquared = -9999;
185
186 if(!getVar(vtx, chisquared, "chiSquared")) {
187 bad_vtx = true;
188 ATH_MSG_WARNING("VertexFittingSvc::Validate_Vertex -- not valid vtx chiSquared!!!");
189 }
190
191 float numberdof = -9999;
192
193 if(!getVar(vtx, numberdof, "numberDoF")) {
194 bad_vtx = true;
195 ATH_MSG_WARNING("VertexFittingSvc::Validate_Vertex -- not valid vtx numberDoF!!!");
196 }
197
198 if(std::isnan(vtx->x()) || std::isnan(vtx->y()) || std::isnan(vtx->z())) {
199 bad_vtx = true;
200 ATH_MSG_WARNING("VertexFittingSvc::Validate_Vertex -- vertex coordinate is nan");
201 }
202
203 if(bad_vtx) {
204 ATH_MSG_WARNING("VertexFittingSvc::Validate_Vertex -- bad vertex!!!");
205 ATH_MSG_INFO(printPromptVertexAsStr(vtx, msg(MSG::WARNING)));
206 }
207
208 return !bad_vtx;
209}
210
211//=============================================================================
212void Prompt::VertexFittingTool::removeDoubleEntries(std::vector<const xAOD::TrackParticle*>& tracks)
213{
214 const unsigned nbefore = tracks.size();
215
216 sort(tracks.begin(), tracks.end());
217
218 typename std::vector<const xAOD::TrackParticle*>::iterator TransfEnd = std::unique(tracks.begin(), tracks.end());
219
220 tracks.erase(TransfEnd, tracks.end());
221
222 if(nbefore != tracks.size()) {
223 ATH_MSG_DEBUG("removeDoubleEntries nbefore != tracks.size()): " << nbefore << " != " << tracks.size());
224 }
225}
226
227//=============================================================================
229 const FittingInput &input,
230 xAOD::Vertex *secVtx
231)
232{
233 //
234 // Decorate secondary vertex with all useful information
235 //
236 if(!secVtx) {
237 ATH_MSG_WARNING("decorateNewSecondaryVertex - invalid pointer");
238 return false;
239 }
240
241 //
242 // Decorate secondary vertex with the distance/norm_distance it from Prmary Vertex, Refitted Primary vertex and Refitted Primary Vertex that removed lepton itself.
243 //
244 float distToPriVtx = -1;
245 float normDistToPriVtx = -1;
246 float distToRefittedPriVtx = -1;
247 float normDistToRefittedPriVtx = -1;
248 float distToRefittedRmLepPriVtx = -1;
249 float normDistToRefittedRmLepPriVtx = -1;
250
251 if(input.priVtx) {
252 distToPriVtx = Prompt::getDistance(input.priVtx->position(), secVtx->position());
253 normDistToPriVtx = Prompt::getNormDist(input.priVtx->position(), secVtx->position(), secVtx->covariance(), msg(MSG::WARNING));
254 }
255
256 if(input.refittedPriVtx) {
257 distToRefittedPriVtx = Prompt::getDistance(input.refittedPriVtx->position(), secVtx->position());
258 normDistToRefittedPriVtx = Prompt::getNormDist(input.refittedPriVtx->position(), secVtx->position(), secVtx->covariance(), msg(MSG::WARNING));
259 }
260
261 if(input.refittedPriVtxWithoutLep) {
262 distToRefittedRmLepPriVtx = Prompt::getDistance(input.refittedPriVtxWithoutLep->position(), secVtx->position());
263 normDistToRefittedRmLepPriVtx = Prompt::getNormDist(input.refittedPriVtxWithoutLep->position(), secVtx->position(), secVtx->covariance(), msg(MSG::WARNING));
264 }
265
266 (*m_distToPriVtx) (*secVtx) = distToPriVtx;
267 (*m_normDistToPriVtx) (*secVtx) = normDistToPriVtx;
268 (*m_distToRefittedPriVtx) (*secVtx) = distToRefittedPriVtx;
269 (*m_normDistToRefittedPriVtx) (*secVtx) = normDistToRefittedPriVtx;
270 (*m_distToRefittedRmLepPriVtx) (*secVtx) = distToRefittedRmLepPriVtx;
271 (*m_normDistToRefittedRmLepPriVtx)(*secVtx) = normDistToRefittedRmLepPriVtx;
272
273 return true;
274}
275
276//=============================================================================
278 const EventContext& ctx,
279 const std::vector<const xAOD::TrackParticle*> &tracks,
280 const xAOD::TrackParticleContainer *inDetTracks,
281 const Amg::Vector3D& seed
282)
283{
284 //
285 // Fit one vertex with given tracks
286 //
287 std::vector<const xAOD::TrackParticle*> tracksForFit(tracks);
288
289 ATH_MSG_DEBUG("getSecondaryVertexWithSeed -- before remove " << tracksForFit.size());
290
291 removeDoubleEntries(tracksForFit);
292
293 ATH_MSG_DEBUG("getSecondaryVertexWithSeed -- after remove " << tracksForFit.size());
294
295 if(tracksForFit.size() < 2) {
296 ATH_MSG_WARNING("getSecondaryVertexWithSeed -- cannot fit vertex with one or zero input track: ntrack=" << tracksForFit.size());
297 return 0;
298 }
299
300 //
301 // Run fit
302 //
303 ATH_MSG_DEBUG(name() << "::getSecondaryVertexWithSeed -- N tracks = " << tracksForFit.size());
304
305 for(const xAOD::TrackParticle* track: tracksForFit) {
306 ATH_MSG_DEBUG( name() << "::getSecondaryVertexWithSeed -- track pt, eta = " << track->pt() << "," << track->eta());
307 ATH_MSG_DEBUG( name() << "::getSecondaryVertexWithSeed -- track chi2 = " << track->chiSquared());
308 }
309
310 std::unique_ptr<xAOD::Vertex> newVertex;
311 std::unique_ptr<xAOD::Vertex> seedVertex;
312
314 seedVertex = m_seedVertexFitter->fit(ctx, tracksForFit, seed);
315
316 if(seedVertex.get() && !isValidVertex(seedVertex.get())) {
317 ATH_MSG_DEBUG("getSecondaryVertexWithSeed -- failed to fit seed vertex");
318
319 seedVertex.reset();
320 }
321 }
322
323 if(seedVertex.get()) {
324 newVertex = m_vertexFitter->fit(ctx, tracksForFit, seedVertex->position());
325 }
326 else {
327 newVertex = m_vertexFitter->fit(ctx, tracksForFit, seed);
328 }
329
330 if(!newVertex) {
331 ATH_MSG_INFO("getSecondaryVertexWithSeed -- failed to fit vertex and fitter returned null xAOD::Vertex pointer");
332 return 0;
333 }
334
335 //
336 // Save vertex tracks
337 //
338 std::vector<ElementLink< xAOD::TrackParticleContainer> > tpLinks;
339
340 if(inDetTracks) {
341 //
342 // Record links to ID tracks if container pointer is provided
343 //
344 for(const xAOD::TrackParticle *selectedtrack: tracksForFit) {
346
347 tpLink.toContainedElement(*inDetTracks, selectedtrack);
348 tpLinks.push_back(tpLink);
349 }
350 }
351
352 newVertex->setTrackParticleLinks(tpLinks);
353
354 TLorentzVector Momentum;
355
356 for(const xAOD::TrackParticle* track: tracksForFit) {
357 Momentum += static_cast<TLorentzVector>(track->p4());
358 }
359
360 xAOD::SecVtxHelper::setVertexMass(newVertex.get(), Momentum.M()); // "mass"
361
362 return newVertex
363;
364}
365
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
MsgStream & msg() const
std::unique_ptr< SG::AuxElement::Decorator< float > > m_normDistToRefittedRmLepPriVtx
Gaudi::Property< std::string > m_normDistToRefittedPriVtxName
ToolHandle< Trk::IVertexFitter > m_seedVertexFitter
Gaudi::Property< std::string > m_distToPriVtxName
Gaudi::Property< bool > m_doSeedVertexFit
virtual StatusCode initialize() override
virtual std::unique_ptr< xAOD::Vertex > fitVertexWithPrimarySeed(const EventContext &ctx, const FittingInput &input, const std::vector< const xAOD::TrackParticle * > &tracks, VtxType vtx) override
bool decorateNewSecondaryVertex(const FittingInput &input, xAOD::Vertex *secVtx)
Gaudi::Property< std::string > m_distToRefittedRmLepPriVtxName
virtual StatusCode finalize() override
virtual bool isValidVertex(const xAOD::Vertex *vtx) const override
Gaudi::Property< std::string > m_normDistToRefittedRmLepPriVtxName
ToolHandle< Trk::IVertexFitter > m_vertexFitter
std::unique_ptr< SG::AuxElement::Decorator< float > > m_distToPriVtx
void removeDoubleEntries(std::vector< const xAOD::TrackParticle * > &tracks)
std::unique_ptr< SG::AuxElement::Decorator< float > > m_normDistToPriVtx
std::unique_ptr< SG::AuxElement::Decorator< float > > m_normDistToRefittedPriVtx
Gaudi::Property< std::string > m_distToRefittedPriVtxName
std::unique_ptr< SG::AuxElement::Decorator< float > > m_distToRefittedRmLepPriVtx
Gaudi::Property< std::string > m_normDistToPriVtxName
std::unique_ptr< xAOD::Vertex > getSecondaryVertexWithSeed(const EventContext &ctx, const std::vector< const xAOD::TrackParticle * > &tracks, const xAOD::TrackParticleContainer *inDetTracks, const Amg::Vector3D &seed)
virtual std::unique_ptr< xAOD::Vertex > fitVertexWithSeed(const EventContext &ctx, const FittingInput &input, const std::vector< const xAOD::TrackParticle * > &tracks, const Amg::Vector3D &seed, VtxType vtxType) override
std::unique_ptr< SG::AuxElement::Decorator< float > > m_distToRefittedPriVtx
VertexFittingTool(const std::string &t, const std::string &name, const IInterface *p)
float z() const
Returns the z position.
float y() const
Returns the y position.
const Amg::Vector3D & position() const
Returns the 3-pos.
float x() const
Returns the x position.
const std::vector< float > & covariance() const
Returns the covariance matrix as a simple vector of values.
Eigen::Matrix< double, 3, 1 > Vector3D
std::string PrintResetStopWatch(TStopwatch &watch)
std::string printPromptVertexAsStr(const xAOD::Vertex *vtx, MsgStream &msg)
bool getVar(T1 &obj, T2 &value, const std::string &var_name)
Definition PromptUtils.h:62
double getNormDist(const Amg::Vector3D &PrimVtx, const Amg::Vector3D &SecVtx, const std::vector< float > &ErrorMatrix, MsgStream &msg)
double getDistance(const xAOD::Vertex *vtx1, const xAOD::Vertex *vtx2)
STL namespace.
DataModel_detail::iterator< DVL > unique(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of unique for DataVector/List.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
void setVertexMass(xAOD::Vertex *, float value)
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
MsgStream & msg
Definition testRead.cxx:32