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.empty() ) {
32 ATH_MSG_DEBUG("Extrapolator is None/Empty. Tool-dependent features will be disabled.");
33 } else {
34 // Only try to retrieve if a name was actually provided
35 if ( m_extrapolator.retrieve().isFailure() ) {
36 ATH_MSG_FATAL("Failed to retrieve tool " << m_extrapolator);
37 return StatusCode::FAILURE;
38 }
39 }
40 // updator
41 if (m_Updator.retrieve().isFailure()) {
42 ATH_MSG_FATAL("Failed to retrieve tool " << m_Updator);
43 return StatusCode::FAILURE;
44 }
45
46 // linearized track factory
47 if ( m_linFactory.retrieve().isFailure() )
48 {
49 ATH_MSG_FATAL("Failed to retrieve tool " << m_linFactory );
50 return StatusCode::FAILURE;
51 }
52
53 return StatusCode::SUCCESS;
54 }//end of initialize method
55
56
57 std::unique_ptr<ImpactParametersAndSigma> TrackToVertexIPEstimator::estimate(const EventContext &ctx, const xAOD::TrackParticle * track, const xAOD::Vertex * vtx, bool doRemoval) const
58 {
59 if(track && vtx)
60 {
61 return estimate(ctx, &(track->perigeeParameters()),&(track->perigeeParameters()),vtx,doRemoval);
62 }
63 ATH_MSG_INFO( "Empty TrackParticle or Vertex pointer passed. Returning zero " );
64 return nullptr;
65 //end of track particle validity check
66 }//end of method using track particles
67
68 std::unique_ptr<ImpactParametersAndSigma> TrackToVertexIPEstimator::estimate(const EventContext &ctx, const xAOD::TrackParticle * track, const xAOD::TrackParticle * newtrack, const xAOD::Vertex * vtx, bool doRemoval) const
69 {
70 if(track && vtx)
71 {
72 return estimate(ctx, &(track->perigeeParameters()),&(newtrack->perigeeParameters()),vtx,doRemoval);
73 }
74 ATH_MSG_INFO( "Empty TrackParticle or Vertex pointer passed. Returning zero " );
75 return nullptr;
76 //end of track particle validity check
77 }//end of method using track particles
78
79
80
81
82 std::unique_ptr<ImpactParametersAndSigma> TrackToVertexIPEstimator::estimate(
83 const EventContext &ctx,
84 const TrackParameters * track, const xAOD::Vertex * vtx, bool doRemoval) const
85 {
86 if(track && vtx){
87 return estimate(ctx, track,track,vtx,doRemoval);
88 }
89 ATH_MSG_INFO( "Empty TrackParticle or Vertex pointer passed. Returning zero " );
90 return nullptr;
91 //end of track particle validity check
92
93 }//end of parameterBase estimate method
94
95 std::unique_ptr<ImpactParametersAndSigma> TrackToVertexIPEstimator::estimate(
96 const EventContext &ctx,
97 const TrackParameters * track, const TrackParameters * newtrack, const xAOD::Vertex * vtx, bool doRemoval) const
98 {
99
100 if (vtx==nullptr)
101 {
102 ATH_MSG_WARNING("Vertex is zero pointer. Will not estimate IP of track.");
103 return nullptr;
104 }
105
106 const xAOD::Vertex *newVertex = vtx;
107 if (doRemoval)
108 {
109 newVertex = getUnbiasedVertex(track,vtx);
110 if (newVertex == nullptr) {
111 ATH_MSG_WARNING("Unbiasing of vertex failed. Will not estimate IP of track.");
112 return nullptr;
113 }
114 }
115
116 std::unique_ptr<ImpactParametersAndSigma> IPandSigma=calculate(ctx, newtrack,*newVertex);
117
118 if (doRemoval)
119 {
120 delete newVertex;
121 newVertex=nullptr;
122 }
123
124 return IPandSigma;
125
126 }//end of parameterBase estimate method
127
128
129 std::unique_ptr<ImpactParametersAndSigma> TrackToVertexIPEstimator::calculate(const EventContext &ctx, const TrackParameters * track, const xAOD::Vertex& vtx) const
130 {
131 //estimating the d0 and its significance by propagating the trajectory state towards
132 //the vertex position. By this time the vertex should NOT contain this trajectory anymore
133
134 //estrapolating to the perigee of the reconstructed vertex
135 const Amg::Vector3D & lp = vtx.position();
136 PerigeeSurface perigeeSurface(lp);
137 const Trk::Perigee* extrapolatedParameters =
138 dynamic_cast<const Trk::Perigee*>(
140 ->extrapolate(ctx, *track, perigeeSurface)
141 .release());
142 if (extrapolatedParameters && extrapolatedParameters->covariance()) {
143
144 //actual calculation of d0 and sigma.
145 const AmgVector(5) & par = extrapolatedParameters->parameters();
146 const double d0 = par[Trk::d0];
147 const double z0 = par[Trk::z0];
148 const double phi = par[Trk::phi];
149 const double theta = par[Trk::theta];
150
151 AmgSymMatrix(2) vrtXYCov = vtx.covariancePosition().block<2,2>(0,0);
152
153 const AmgSymMatrix(5) & perigeeCov = *(extrapolatedParameters->covariance());
154 // std::cout<<"Perigee covariance: "<<perigeeCov<<std::endl;
155
156 //d0phi->cartesian Jacobian
157 Amg::Vector2D d0JacXY(-sin(phi), cos(phi));
158
159
160 auto newIPandSigma=std::make_unique<ImpactParametersAndSigma>();
161 newIPandSigma->IPd0=d0;
162 double d0_PVcontrib=d0JacXY.transpose()*(vrtXYCov*d0JacXY);
163 if (d0_PVcontrib>=0)
164 {
165 newIPandSigma->sigmad0=sqrt(d0_PVcontrib+perigeeCov(Trk::d0,Trk::d0));
166 newIPandSigma->PVsigmad0=sqrt(d0_PVcontrib);
167 }
168 else
169 {
170 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;
171 newIPandSigma->sigmad0=sqrt(perigeeCov(Trk::d0,Trk::d0));
172 newIPandSigma->PVsigmad0=0;
173 }
174
175 AmgSymMatrix(2) covPerigeeZ0Theta;
176 covPerigeeZ0Theta(0,0)=perigeeCov(Trk::z0,Trk::z0);
177 covPerigeeZ0Theta(0,1)=perigeeCov(Trk::z0,Trk::theta);
178 covPerigeeZ0Theta(1,0)=perigeeCov(Trk::theta,Trk::z0);
179 covPerigeeZ0Theta(1,1)=perigeeCov(Trk::theta,Trk::theta);
180
181 double vrtZZCov = vtx.covariancePosition()(Trk::z,Trk::z);
182
183 Amg::Vector2D IPz0JacZ0Theta (sin(theta), z0*cos(theta));
184 if (vrtZZCov>=0)
185 {
186 newIPandSigma->IPz0SinTheta=z0*sin(theta);
187 newIPandSigma->sigmaz0SinTheta=
188 sqrt(IPz0JacZ0Theta.transpose()*(covPerigeeZ0Theta*IPz0JacZ0Theta)+sin(theta)*vrtZZCov*sin(theta));
189 newIPandSigma->PVsigmaz0SinTheta=sqrt(sin(theta)*vrtZZCov*sin(theta));
190 newIPandSigma->IPz0 = z0;
191 newIPandSigma->sigmaz0 = std::sqrt( vrtZZCov + perigeeCov(Trk::z0,Trk::z0) );
192 newIPandSigma->PVsigmaz0 = std::sqrt( vrtZZCov );
193 }
194 else
195 {
196 ATH_MSG_WARNING(" The contribution to z0_err: " << vrtZZCov << " from PV is negative: critical error in PV error matrix! Removing contribution from PV ... ");
197 newIPandSigma->IPz0SinTheta=z0*sin(theta);
198 double temp = (IPz0JacZ0Theta.transpose()*(covPerigeeZ0Theta*IPz0JacZ0Theta));
199 newIPandSigma->sigmaz0SinTheta=sqrt(temp);
200 newIPandSigma->PVsigmaz0SinTheta=0;
201
202 newIPandSigma->IPz0 = z0;
203 newIPandSigma->sigmaz0 = std::sqrt( perigeeCov(Trk::z0,Trk::z0) );
204 newIPandSigma->PVsigmaz0 = 0;
205 }
206
207
208 delete extrapolatedParameters;
209 return newIPandSigma;
210 }
211 ATH_MSG_DEBUG ("Cannot extrapolate the trajectory state. Returning null. ");
212 return nullptr;
213 //end of successfull extrapolation check
214 }//end of actual calculation method
215
216
217
218 double TrackToVertexIPEstimator::get3DLifetimeSignOfTrack(const EventContext &ctx, const TrackParameters & track,
219 const Amg::Vector3D & jetMomentum,
220 const xAOD::Vertex & primaryVertex) const
221 {
222 const Amg::Vector3D & lp = primaryVertex.position();
223 PerigeeSurface perigeeSurface(lp);
224
225 std::unique_ptr<const Trk::TrackParameters> extrapolatedParameters =
226 m_extrapolator->extrapolate(
227 ctx, track, perigeeSurface);
228
229 if (!extrapolatedParameters) return 0.;
230
231 const Amg::Vector3D & primaryPos=primaryVertex.position();
232 const Amg::Vector3D & trackPos=extrapolatedParameters->position();
233 const Amg::Vector3D & trackMom=extrapolatedParameters->momentum();
234
235 double sign=(jetMomentum.cross(trackMom)).dot(trackMom.cross(primaryPos-trackPos));
236
237 return sign>=0.?1.:-1;
238 }
239
241 const TrackParameters & track,
242 const Amg::Vector3D & jetMomentum,
243 const xAOD::Vertex & primaryVertex) const
244 {
245 const Amg::Vector3D & lp = primaryVertex.position();
246 PerigeeSurface perigeeSurface(lp);
247
248 std::unique_ptr<const Trk::TrackParameters> extrapolatedParameters =
249 m_extrapolator->extrapolate(
250 ctx, track, perigeeSurface);
251
252 if (!extrapolatedParameters) return 0.;
253
254 double trackD0 = extrapolatedParameters->parameters()[Trk::d0];
255 double trackPhi = extrapolatedParameters->parameters()[Trk::phi];
256 double vs = sinf( atan2(jetMomentum.y(),jetMomentum.x()) - trackPhi )*trackD0;
257
258 return (vs>=0. ? 1. : -1.);
259 }
260
261
263 const TrackParameters & track,
264 const Amg::Vector3D & jetMomentum,
265 const xAOD::Vertex & primaryVertex) const
266 {
267
268 const Amg::Vector3D & lp = primaryVertex.position();
269 PerigeeSurface perigeeSurface(lp);
270
271 std::unique_ptr<const Trk::TrackParameters> extrapolatedParameters =
272 m_extrapolator->extrapolate(
273 ctx, track, perigeeSurface);
274
275 if (!extrapolatedParameters) return 0.;
276
277 double trackTheta = extrapolatedParameters->parameters()[Trk::theta];
278 double trackZ0 = extrapolatedParameters->parameters()[Trk::z0];
279 double trackEta = -logf(tanf(trackTheta/2.));
280 double jetEta = jetMomentum.eta();
281 double zs = (jetEta - trackEta)*trackZ0;
282 return (zs>=0. ? 1. : -1.);
283 }
284
285
287
289 {
290 if(track)
291 {
292 return getUnbiasedVertex(&(track->perigeeParameters()),vtx);
293 }
294 msg(MSG::INFO) << "Empty xAOD::TrackParticle pointer passed. Returning zero " << endmsg;
295 return nullptr;
296 //end of track particle validity check
297 }
298
300 {
301 if (!track) {
302 msg(MSG::INFO) << "Empty Trk::TrackParameter pointer passed. Returning zero " << endmsg;
303 return nullptr;
304 }
305 if (!vtx) {
306 msg(MSG::INFO) << "Empty xAOD::Vertex pointer passed. Returning zero " << endmsg;
307 return nullptr;
308 }
309
310 if (vtx->nTrackParticles() == 0)
311 {
312 ATH_MSG_DEBUG("This vertex has no associated tracks. Normal if beam spot is used. Vertex already unbiased");
313 return new xAOD::Vertex(*vtx);
314 }
315
316 //create new vertex for output
317 xAOD::Vertex *outputVertex = new xAOD::Vertex(*vtx);
318 outputVertex->clearTracks(); //remove all tracks -> will add them back one by one
319 if (outputVertex->vxTrackAtVertexAvailable()) outputVertex->vxTrackAtVertex().clear(); //remove all VxTrackAtVertex
320
321 bool tmpLinTrack = false; //do we created a new linearised track?
322
323 //loop over tracks
324 const Amg::Vector3D & pos = track->position();
325 const Amg::Vector3D & mom = track->momentum();
326 for (unsigned int itrk=0; itrk < vtx->nTrackParticles(); ++itrk) {
327 const Perigee& testTP = vtx->trackParticle(itrk)->perigeeParameters();
328 if ((testTP.position() == pos) and (testTP.momentum() == mom)) {
329 //track found, now unbias the vertex using linearized track
330 const LinearizedTrack *linTrack = nullptr;
331 double trackWeight(0.0);
332 //first check if a VxTrackAtVertex is already available with linearized track
333 if (vtx->vxTrackAtVertexAvailable()) {
334 if (vtx->vxTrackAtVertex().size() > itrk) {
335 linTrack = vtx->vxTrackAtVertex()[itrk].linState();
336 trackWeight = vtx->vxTrackAtVertex()[itrk].weight();
337 }
338 }
339 //if linearized track is not available, create it
340 if (!linTrack) {
341 linTrack = m_linFactory->linearizedTrack(track, vtx->position());
342 trackWeight = vtx->trackWeight(itrk);
343 if (!linTrack) {
344 ATH_MSG_INFO("Failing to linearized track. Returning biased vertex.");
345 outputVertex->addTrackAtVertex(vtx->trackParticleLinks()[itrk], vtx->trackWeight(itrk));
346 if (vtx->vxTrackAtVertexAvailable()) {
347 outputVertex->vxTrackAtVertex().push_back(vtx->vxTrackAtVertex()[itrk]);//will clone everything inside -> output vertex owns all the memory
348 }
349 continue;
350 }
351 tmpLinTrack = true;
352 }
353 //now update vertex position removing the linearized track, and do not add the track back to the output vertex
354 const IVertexUpdator::positionUpdateOutcome & reducedVertex = m_Updator->positionUpdate(*vtx, linTrack, trackWeight,IVertexUpdator::removeTrack);
355
356 //calculate updated chi2
357 double chi2 = vtx->chiSquared();
358 double trk_chi = m_Updator->trackParametersChi2( reducedVertex, linTrack );
359 chi2 += -1 * (m_Updator->vertexPositionChi2(*vtx, reducedVertex) + trackWeight * trk_chi);
360
361 //calculate updated ndf
362 double ndf = vtx->numberDoF();
363 ndf += -1 * trackWeight * (2.0);
364
365 //reducedVertex has the updated position and covariance
366 outputVertex->setPosition(reducedVertex.position);
367 outputVertex->setCovariancePosition(reducedVertex.covariancePosition);
368
369 //chi2 and ndf now store the updated FitQuality
370 outputVertex->setFitQuality( chi2, ndf );
371
372 if (tmpLinTrack) delete linTrack; //only delete if it was created new, and doesn't belong to a vertex
373 } else {
374 //track not to be removed. Add back the track to the vertex collection
375 outputVertex->addTrackAtVertex(vtx->trackParticleLinks()[itrk], vtx->trackWeight(itrk));
376 if (vtx->vxTrackAtVertexAvailable()) {
377 outputVertex->vxTrackAtVertex().push_back(vtx->vxTrackAtVertex()[itrk]);//will clone everything inside -> output vertex owns all the memory
378 }
379 }
380 }
381 return outputVertex;
382
383 }
384
385
386
387 std::unique_ptr<ImpactParametersAndSigma> TrackToVertexIPEstimator::estimate(const EventContext &ctx,
388 const xAOD::TrackParticle * track,
389 const xAOD::Vertex* vtx)const
390 {
391
392 if(track && vtx ){
393 return estimate(ctx, &(track->perigeeParameters()), vtx);
394 }
395 return nullptr;
396
397 }
398
399 std::unique_ptr<ImpactParametersAndSigma> TrackToVertexIPEstimator::estimate(
400 const EventContext &ctx,
401 const TrackParameters * track,
402 const xAOD::Vertex* vtx)const
403 {
404
405 if(track && vtx ){
406 return calculate(ctx, track , *vtx);
407 }
408 return nullptr;
409
410 }
411
412}//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.
ToolHandle< Trk::IVertexUpdator > m_Updator
virtual StatusCode initialize() override
Default Athena interface methods.
virtual double get2DLifetimeSignOfTrack(const EventContext &ctx, const TrackParameters &track, const Amg::Vector3D &jetDirection, const xAOD::Vertex &primaryVertex) const override
virtual xAOD::Vertex * getUnbiasedVertex(const xAOD::TrackParticle *track, const xAOD::Vertex *vtx) const override
virtual std::unique_ptr< ImpactParametersAndSigma > estimate(const EventContext &ctx, const xAOD::TrackParticle *track, const xAOD::Vertex *vtx, bool doRemoval) const override
Estimate methods returning a d0 and its calculated sigma.
ToolHandle< Trk::IExtrapolator > m_extrapolator
TrackToVertexIPEstimator(const std::string &t, const std::string &n, const IInterface *p)
Default Athena interface constructor and destructor.
ToolHandle< Trk::IVertexLinearizedTrackFactory > m_linFactory
virtual double get3DLifetimeSignOfTrack(const EventContext &ctx, const TrackParameters &track, const Amg::Vector3D &jetDirection, const xAOD::Vertex &primaryVertex) const override
virtual double getZLifetimeSignOfTrack(const EventContext &ctx, const TrackParameters &track, const Amg::Vector3D &jetDirection, const xAOD::Vertex &primaryVertex) const override
std::unique_ptr< ImpactParametersAndSigma > calculate(const EventContext &ctx, const TrackParameters *track, const xAOD::Vertex &vtx) const
A method calculating the do and its error.
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