ATLAS Offline Software
Loading...
Searching...
No Matches
TrackToVertexIPEstimator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "TrkTrack/Track.h"
11
14#include "xAODTracking/Vertex.h"
15
16namespace Trk
17{
18
19 TrackToVertexIPEstimator::TrackToVertexIPEstimator(const std::string& t, const std::string& n, const IInterface* p):
20 base_class(t,n,p)
21 {
22 }
23
25
27 {
28
29 // uploading the corresponding tools
30 // extrapolator
31 if (m_extrapolator.retrieve().isFailure()) {
32 ATH_MSG_FATAL("Failed to retrieve tool " << m_extrapolator);
33 return StatusCode::FAILURE;
34 }
35
36 // updator
37 if (m_Updator.retrieve().isFailure()) {
38 ATH_MSG_FATAL("Failed to retrieve tool " << m_Updator);
39 return StatusCode::FAILURE;
40 }
41
42 // linearized track factory
43 if ( m_linFactory.retrieve().isFailure() )
44 {
45 ATH_MSG_FATAL("Failed to retrieve tool " << m_linFactory );
46 return StatusCode::FAILURE;
47 }
48
49 return StatusCode::SUCCESS;
50 }//end of initialize method
51
52
53 std::unique_ptr<ImpactParametersAndSigma> TrackToVertexIPEstimator::estimate(const xAOD::TrackParticle * track, const xAOD::Vertex * vtx, bool doRemoval) const
54 {
55 if(track && vtx)
56 {
57 return estimate(&(track->perigeeParameters()),&(track->perigeeParameters()),vtx,doRemoval);
58 }
59 ATH_MSG_INFO( "Empty TrackParticle or Vertex pointer passed. Returning zero " );
60 return nullptr;
61 //end of track particle validity check
62 }//end of method using track particles
63
64 std::unique_ptr<ImpactParametersAndSigma> TrackToVertexIPEstimator::estimate(const xAOD::TrackParticle * track, const xAOD::TrackParticle * newtrack, const xAOD::Vertex * vtx, bool doRemoval) const
65 {
66 if(track && vtx)
67 {
68 return estimate(&(track->perigeeParameters()),&(newtrack->perigeeParameters()),vtx,doRemoval);
69 }
70 ATH_MSG_INFO( "Empty TrackParticle or Vertex pointer passed. Returning zero " );
71 return nullptr;
72 //end of track particle validity check
73 }//end of method using track particles
74
75
76
77
78 std::unique_ptr<ImpactParametersAndSigma> TrackToVertexIPEstimator::estimate(const TrackParameters * track, const xAOD::Vertex * vtx, bool doRemoval) const
79 {
80 if(track && vtx){
81 return estimate(track,track,vtx,doRemoval);
82 }
83 ATH_MSG_INFO( "Empty TrackParticle or Vertex pointer passed. Returning zero " );
84 return nullptr;
85 //end of track particle validity check
86
87 }//end of parameterBase estimate method
88
89 std::unique_ptr<ImpactParametersAndSigma> TrackToVertexIPEstimator::estimate(const TrackParameters * track, const TrackParameters * newtrack, const xAOD::Vertex * vtx, bool doRemoval) const
90 {
91
92 if (vtx==nullptr)
93 {
94 ATH_MSG_WARNING("Vertex is zero pointer. Will not estimate IP of track.");
95 return nullptr;
96 }
97
98 const xAOD::Vertex *newVertex = vtx;
99 if (doRemoval)
100 {
101 newVertex = getUnbiasedVertex(track,vtx);
102 if (newVertex == nullptr) {
103 ATH_MSG_WARNING("Unbiasing of vertex failed. Will not estimate IP of track.");
104 return nullptr;
105 }
106 }
107
108 std::unique_ptr<ImpactParametersAndSigma> IPandSigma=calculate(newtrack,*newVertex);
109
110 if (doRemoval)
111 {
112 delete newVertex;
113 newVertex=nullptr;
114 }
115
116 return IPandSigma;
117
118 }//end of parameterBase estimate method
119
120
121 std::unique_ptr<ImpactParametersAndSigma> TrackToVertexIPEstimator::calculate(const TrackParameters * track, const xAOD::Vertex& vtx) const
122 {
123 //estimating the d0 and its significance by propagating the trajectory state towards
124 //the vertex position. By this time the vertex should NOT contain this trajectory anymore
125
126 //estrapolating to the perigee of the reconstructed vertex
127 const Amg::Vector3D & lp = vtx.position();
128 PerigeeSurface perigeeSurface(lp);
129 const Trk::Perigee* extrapolatedParameters =
130 dynamic_cast<const Trk::Perigee*>(
132 ->extrapolate(Gaudi::Hive::currentContext(), *track, perigeeSurface)
133 .release());
134 if (extrapolatedParameters && extrapolatedParameters->covariance()) {
135
136 //actual calculation of d0 and sigma.
137 const AmgVector(5) & par = extrapolatedParameters->parameters();
138 const double d0 = par[Trk::d0];
139 const double z0 = par[Trk::z0];
140 const double phi = par[Trk::phi];
141 const double theta = par[Trk::theta];
142
143 AmgSymMatrix(2) vrtXYCov = vtx.covariancePosition().block<2,2>(0,0);
144
145 const AmgSymMatrix(5) & perigeeCov = *(extrapolatedParameters->covariance());
146 // std::cout<<"Perigee covariance: "<<perigeeCov<<std::endl;
147
148 //d0phi->cartesian Jacobian
149 Amg::Vector2D d0JacXY(-sin(phi), cos(phi));
150
151
152 auto newIPandSigma=std::make_unique<ImpactParametersAndSigma>();
153 newIPandSigma->IPd0=d0;
154 double d0_PVcontrib=d0JacXY.transpose()*(vrtXYCov*d0JacXY);
155 if (d0_PVcontrib>=0)
156 {
157 newIPandSigma->sigmad0=sqrt(d0_PVcontrib+perigeeCov(Trk::d0,Trk::d0));
158 newIPandSigma->PVsigmad0=sqrt(d0_PVcontrib);
159 }
160 else
161 {
162 msg(MSG::WARNING) << " The contribution to d0_err: " << d0_PVcontrib << " from PV is negative: critical error in PV error matrix! Removing contribution from PV ... " << endmsg;
163 newIPandSigma->sigmad0=sqrt(perigeeCov(Trk::d0,Trk::d0));
164 newIPandSigma->PVsigmad0=0;
165 }
166
167 AmgSymMatrix(2) covPerigeeZ0Theta;
168 covPerigeeZ0Theta(0,0)=perigeeCov(Trk::z0,Trk::z0);
169 covPerigeeZ0Theta(0,1)=perigeeCov(Trk::z0,Trk::theta);
170 covPerigeeZ0Theta(1,0)=perigeeCov(Trk::theta,Trk::z0);
171 covPerigeeZ0Theta(1,1)=perigeeCov(Trk::theta,Trk::theta);
172
173 double vrtZZCov = vtx.covariancePosition()(Trk::z,Trk::z);
174
175 Amg::Vector2D IPz0JacZ0Theta (sin(theta), z0*cos(theta));
176 if (vrtZZCov>=0)
177 {
178 newIPandSigma->IPz0SinTheta=z0*sin(theta);
179 newIPandSigma->sigmaz0SinTheta=
180 sqrt(IPz0JacZ0Theta.transpose()*(covPerigeeZ0Theta*IPz0JacZ0Theta)+sin(theta)*vrtZZCov*sin(theta));
181 newIPandSigma->PVsigmaz0SinTheta=sqrt(sin(theta)*vrtZZCov*sin(theta));
182 newIPandSigma->IPz0 = z0;
183 newIPandSigma->sigmaz0 = std::sqrt( vrtZZCov + perigeeCov(Trk::z0,Trk::z0) );
184 newIPandSigma->PVsigmaz0 = std::sqrt( vrtZZCov );
185 }
186 else
187 {
188 ATH_MSG_WARNING(" The contribution to z0_err: " << vrtZZCov << " from PV is negative: critical error in PV error matrix! Removing contribution from PV ... ");
189 newIPandSigma->IPz0SinTheta=z0*sin(theta);
190 double temp = (IPz0JacZ0Theta.transpose()*(covPerigeeZ0Theta*IPz0JacZ0Theta));
191 newIPandSigma->sigmaz0SinTheta=sqrt(temp);
192 newIPandSigma->PVsigmaz0SinTheta=0;
193
194 newIPandSigma->IPz0 = z0;
195 newIPandSigma->sigmaz0 = std::sqrt( perigeeCov(Trk::z0,Trk::z0) );
196 newIPandSigma->PVsigmaz0 = 0;
197 }
198
199
200 delete extrapolatedParameters;
201 return newIPandSigma;
202 }
203 ATH_MSG_DEBUG ("Cannot extrapolate the trajectory state. Returning null. ");
204 return nullptr;
205 //end of successfull extrapolation check
206 }//end of actual calculation method
207
208
209
210
211
212
214 const CLHEP::Hep3Vector & jetMomentum,
215 const xAOD::Vertex & primaryVertex) const
216 {
217 Amg::Vector3D eigenJetMomentum(jetMomentum.x(), jetMomentum.y(), jetMomentum.z());
218 return get3DLifetimeSignOfTrack(track, eigenJetMomentum, primaryVertex);
219 }
220
222 const Amg::Vector3D & jetMomentum,
223 const xAOD::Vertex & primaryVertex) const
224 {
225 const Amg::Vector3D & lp = primaryVertex.position();
226 PerigeeSurface perigeeSurface(lp);
227
228 std::unique_ptr<const Trk::TrackParameters> extrapolatedParameters =
229 m_extrapolator->extrapolate(
230 Gaudi::Hive::currentContext(), track, perigeeSurface);
231
232 if (!extrapolatedParameters) return 0.;
233
234 const Amg::Vector3D & primaryPos=primaryVertex.position();
235 const Amg::Vector3D & trackPos=extrapolatedParameters->position();
236 const Amg::Vector3D & trackMom=extrapolatedParameters->momentum();
237
238 double sign=(jetMomentum.cross(trackMom)).dot(trackMom.cross(primaryPos-trackPos));
239
240 return sign>=0.?1.:-1;
241 }
242
243
244
246 const CLHEP::Hep3Vector & jetMomentum,
247 const xAOD::Vertex & primaryVertex) const
248 {
249 Amg::Vector3D eigenJetMomentum(jetMomentum.x(), jetMomentum.y(), jetMomentum.z());
250 return get2DLifetimeSignOfTrack(track, eigenJetMomentum, primaryVertex);
251 }
252
254 const Amg::Vector3D & jetMomentum,
255 const xAOD::Vertex & primaryVertex) const
256 {
257 const Amg::Vector3D & lp = primaryVertex.position();
258 PerigeeSurface perigeeSurface(lp);
259
260 std::unique_ptr<const Trk::TrackParameters> extrapolatedParameters =
261 m_extrapolator->extrapolate(
262 Gaudi::Hive::currentContext(), track, perigeeSurface);
263
264 if (!extrapolatedParameters) return 0.;
265
266 double trackD0 = extrapolatedParameters->parameters()[Trk::d0];
267 double trackPhi = extrapolatedParameters->parameters()[Trk::phi];
268 double vs = sinf( atan2(jetMomentum.y(),jetMomentum.x()) - trackPhi )*trackD0;
269
270 return (vs>=0. ? 1. : -1.);
271 }
272
273
274
275
277 const CLHEP::Hep3Vector & jetMomentum,
278 const xAOD::Vertex & primaryVertex) const
279 {
280 Amg::Vector3D eigenJetMomentum(jetMomentum.x(), jetMomentum.y(), jetMomentum.z());
281 return getZLifetimeSignOfTrack(track, eigenJetMomentum, primaryVertex);
282 }
283
285 const Amg::Vector3D & jetMomentum,
286 const xAOD::Vertex & primaryVertex) const
287 {
288
289 const Amg::Vector3D & lp = primaryVertex.position();
290 PerigeeSurface perigeeSurface(lp);
291
292 std::unique_ptr<const Trk::TrackParameters> extrapolatedParameters =
293 m_extrapolator->extrapolate(
294 Gaudi::Hive::currentContext(), track, perigeeSurface);
295
296 if (!extrapolatedParameters) return 0.;
297
298 double trackTheta = extrapolatedParameters->parameters()[Trk::theta];
299 double trackZ0 = extrapolatedParameters->parameters()[Trk::z0];
300 double trackEta = -logf(tanf(trackTheta/2.));
301 double jetEta = jetMomentum.eta();
302 double zs = (jetEta - trackEta)*trackZ0;
303 return (zs>=0. ? 1. : -1.);
304 }
305
306
308
310 {
311 if(track)
312 {
313 return getUnbiasedVertex(&(track->perigeeParameters()),vtx);
314 }
315 msg(MSG::INFO) << "Empty xAOD::TrackParticle pointer passed. Returning zero " << endmsg;
316 return nullptr;
317 //end of track particle validity check
318 }
319
321 {
322 if (!track) {
323 msg(MSG::INFO) << "Empty Trk::TrackParameter pointer passed. Returning zero " << endmsg;
324 return nullptr;
325 }
326 if (!vtx) {
327 msg(MSG::INFO) << "Empty xAOD::Vertex pointer passed. Returning zero " << endmsg;
328 return nullptr;
329 }
330
331 if (vtx->nTrackParticles() == 0)
332 {
333 ATH_MSG_DEBUG("This vertex has no associated tracks. Normal if beam spot is used. Vertex already unbiased");
334 return new xAOD::Vertex(*vtx);
335 }
336
337 //create new vertex for output
338 xAOD::Vertex *outputVertex = new xAOD::Vertex(*vtx);
339 outputVertex->clearTracks(); //remove all tracks -> will add them back one by one
340 if (outputVertex->vxTrackAtVertexAvailable()) outputVertex->vxTrackAtVertex().clear(); //remove all VxTrackAtVertex
341
342 bool tmpLinTrack = false; //do we created a new linearised track?
343
344 //loop over tracks
345 const Amg::Vector3D & pos = track->position();
346 const Amg::Vector3D & mom = track->momentum();
347 for (unsigned int itrk=0; itrk < vtx->nTrackParticles(); ++itrk) {
348 const Perigee& testTP = vtx->trackParticle(itrk)->perigeeParameters();
349 if ((testTP.position() == pos) and (testTP.momentum() == mom)) {
350 //track found, now unbias the vertex using linearized track
351 const LinearizedTrack *linTrack = nullptr;
352 double trackWeight(0.0);
353 //first check if a VxTrackAtVertex is already available with linearized track
354 if (vtx->vxTrackAtVertexAvailable()) {
355 if (vtx->vxTrackAtVertex().size() > itrk) {
356 linTrack = vtx->vxTrackAtVertex()[itrk].linState();
357 trackWeight = vtx->vxTrackAtVertex()[itrk].weight();
358 }
359 }
360 //if linearized track is not available, create it
361 if (!linTrack) {
362 linTrack = m_linFactory->linearizedTrack(track, vtx->position());
363 trackWeight = vtx->trackWeight(itrk);
364 if (!linTrack) {
365 ATH_MSG_INFO("Failing to linearized track. Returning biased vertex.");
366 outputVertex->addTrackAtVertex(vtx->trackParticleLinks()[itrk], vtx->trackWeight(itrk));
367 if (vtx->vxTrackAtVertexAvailable()) {
368 outputVertex->vxTrackAtVertex().push_back(vtx->vxTrackAtVertex()[itrk]);//will clone everything inside -> output vertex owns all the memory
369 }
370 continue;
371 }
372 tmpLinTrack = true;
373 }
374 //now update vertex position removing the linearized track, and do not add the track back to the output vertex
375 const IVertexUpdator::positionUpdateOutcome & reducedVertex = m_Updator->positionUpdate(*vtx, linTrack, trackWeight,IVertexUpdator::removeTrack);
376
377 //calculate updated chi2
378 double chi2 = vtx->chiSquared();
379 double trk_chi = m_Updator->trackParametersChi2( reducedVertex, linTrack );
380 chi2 += -1 * (m_Updator->vertexPositionChi2(*vtx, reducedVertex) + trackWeight * trk_chi);
381
382 //calculate updated ndf
383 double ndf = vtx->numberDoF();
384 ndf += -1 * trackWeight * (2.0);
385
386 //reducedVertex has the updated position and covariance
387 outputVertex->setPosition(reducedVertex.position);
388 outputVertex->setCovariancePosition(reducedVertex.covariancePosition);
389
390 //chi2 and ndf now store the updated FitQuality
391 outputVertex->setFitQuality( chi2, ndf );
392
393 if (tmpLinTrack) delete linTrack; //only delete if it was created new, and doesn't belong to a vertex
394 } else {
395 //track not to be removed. Add back the track to the vertex collection
396 outputVertex->addTrackAtVertex(vtx->trackParticleLinks()[itrk], vtx->trackWeight(itrk));
397 if (vtx->vxTrackAtVertexAvailable()) {
398 outputVertex->vxTrackAtVertex().push_back(vtx->vxTrackAtVertex()[itrk]);//will clone everything inside -> output vertex owns all the memory
399 }
400 }
401 }
402 return outputVertex;
403
404 }
405
406
407
408 std::unique_ptr<ImpactParametersAndSigma> TrackToVertexIPEstimator::estimate(const xAOD::TrackParticle * track,
409 const xAOD::Vertex* vtx)const
410 {
411
412 if(track && vtx ){
413 return estimate( &(track->perigeeParameters()), vtx);
414 }
415 return nullptr;
416
417 }
418
419 std::unique_ptr<ImpactParametersAndSigma> TrackToVertexIPEstimator::estimate(const TrackParameters * track,
420 const xAOD::Vertex* vtx)const
421 {
422
423 if(track && vtx ){
424 return calculate( track , *vtx);
425 }
426 return nullptr;
427
428 }
429
430}//end of namespace definitions
#define endmsg
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define AmgSymMatrix(dim)
#define AmgVector(rows)
int sign(int a)
const Amg::Vector3D & momentum() const
Access method for the momentum.
const Amg::Vector3D & position() const
Access method for the position.
Class describing the Line to which the Perigee refers to.
virtual double get2DLifetimeSignOfTrack(const TrackParameters &track, const Amg::Vector3D &jetDirection, const xAOD::Vertex &primaryVertex) const override
ToolHandle< Trk::IVertexUpdator > m_Updator
virtual double getZLifetimeSignOfTrack(const TrackParameters &track, const Amg::Vector3D &jetDirection, const xAOD::Vertex &primaryVertex) const override
std::unique_ptr< ImpactParametersAndSigma > calculate(const TrackParameters *track, const xAOD::Vertex &vtx) const
A method calculating the do and its error.
virtual StatusCode initialize() override
Default Athena interface methods.
virtual xAOD::Vertex * getUnbiasedVertex(const xAOD::TrackParticle *track, const xAOD::Vertex *vtx) const override
ToolHandle< Trk::IExtrapolator > m_extrapolator
virtual std::unique_ptr< ImpactParametersAndSigma > estimate(const xAOD::TrackParticle *track, const xAOD::Vertex *vtx, bool doRemoval) const override
Estimate methods returning a d0 and its calculated sigma.
virtual double get3DLifetimeSignOfTrack(const TrackParameters &track, const Amg::Vector3D &jetDirection, const xAOD::Vertex &primaryVertex) const override
TrackToVertexIPEstimator(const std::string &t, const std::string &n, const IInterface *p)
Default Athena interface constructor and destructor.
ToolHandle< Trk::IVertexLinearizedTrackFactory > m_linFactory
const Trk::Perigee & perigeeParameters() const
Returns the Trk::MeasuredPerigee track parameters.
size_t nTrackParticles() const
Get the number of tracks associated with this vertex.
void clearTracks()
Remove all tracks from the vertex.
void setCovariancePosition(const AmgSymMatrix(3)&covariancePosition)
Sets the vertex covariance matrix.
void addTrackAtVertex(const ElementLink< TrackParticleContainer > &tr, float weight=1.0)
Add a new track to the vertex.
const TrackParticleLinks_t & trackParticleLinks() const
Get all the particles associated with the vertex.
const TrackParticle * trackParticle(size_t i) const
Get the pointer to a given track that was used in vertex reco.
float numberDoF() const
Returns the number of degrees of freedom of the vertex fit as float.
void setPosition(const Amg::Vector3D &position)
Sets the 3-position.
bool vxTrackAtVertexAvailable() const
Check if VxTrackAtVertices are attached to the object.
float chiSquared() const
Returns the of the vertex fit as float.
std::vector< Trk::VxTrackAtVertex > & vxTrackAtVertex()
Non-const access to the VxTrackAtVertex vector.
void setFitQuality(float chiSquared, float numberDoF)
Set the 'Fit Quality' information.
const Amg::Vector3D & position() const
Returns the 3-pos.
float trackWeight(size_t i) const
Get the weight of a given track in the vertex reconstruction.
double chi2(TH1 *h0, TH1 *h1)
static std::string release
Definition computils.h:50
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Ensure that the ATLAS eigen extensions are properly loaded.
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ z
global position (cartesian)
Definition ParamDefs.h:57
@ theta
Definition ParamDefs.h:66
@ phi
Definition ParamDefs.h:75
@ d0
Definition ParamDefs.h:63
@ z0
Definition ParamDefs.h:64
ParametersBase< TrackParametersDim, Charged > TrackParameters
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
MsgStream & msg
Definition testRead.cxx:32