ATLAS Offline Software
Loading...
Searching...
No Matches
KalmanVertexUpdator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "GaudiKernel/MsgStream.h"
11
12namespace Trk{
13
14 KalmanVertexUpdator::KalmanVertexUpdator(const std::string& t, const std::string& n, const IInterface* p):
15 AthAlgTool(t,n,p)
16 {
17 declareInterface<IVertexUpdator>(this);
18 }
19
21 = default;
22
24 {
25 StatusCode sc = AlgTool::initialize();
26 if(sc.isFailure())
27 {
28 msg(MSG::ERROR)<<" Unable to initialize the AlgTool"<<endmsg;
29 return StatusCode::FAILURE;
30 }
31
32 return StatusCode::SUCCESS;
33 }
34
35
40
41
46
47
49 {
50
51 //getting tracks at vertex
52 std::vector<Trk::VxTrackAtVertex> & tracksAtVertex = vtx.vxTrackAtVertex();
53
54 //in case one wants to remove the track, one should be sure that this track
55 //is already fitted to the vertex
56 auto righttrack = std::find(tracksAtVertex.begin(), tracksAtVertex.end(), trk);
57 // if it is not part of the vertex (which includes a possible empty vertex), we either add it or give up
58 // in case we are removing tracks
59 if (righttrack == tracksAtVertex.end())
60 {
61 ATH_MSG_VERBOSE ("The track requested for removal or adding is not found in the vector of tracks");
62 // removal - can not proceed
63 if (mode == IVertexUpdator::removeTrack) {
64 ATH_MSG_ERROR ("During remove track has to be already attached to the vertex");
65 msg(MSG::ERROR) << "The copy of initial xAOD::Vertex returned" << endmsg;
66 return &vtx;
67 }
68 // addition - here this is expected behaviour
69
70 righttrack = tracksAtVertex.insert(tracksAtVertex.end(),trk);
71 ATH_MSG_VERBOSE ("Updating vertex with new track which is still not attached to vertex. Adding it before updating...");
72
73 }
74
75 //all safe, call the position update
76 // chi and ndf
77 // track weight and old vertex
78
79 double trkWeight = trk.weight();
80
81 AmgSymMatrix(3) vrt_inverse;
82 bool invertible;
83 vtx.covariancePosition().computeInverseWithCheck(vrt_inverse,invertible);
84
85 if(!invertible) {
86 ATH_MSG_VERBOSE ("The vertex's cov is not invertible, quit updating.");
87 return &vtx;
88 }
89 const IVertexUpdator::positionUpdateOutcome & fit_vrt = positionUpdate( vtx, trk.linState(), trkWeight, mode);
90
91 double chi2 = vtx.chiSquared();
92 double trk_chi = trackParametersChi2( fit_vrt, trk.linState() );
93 if(trk_chi==-999.){
94 ATH_MSG_VERBOSE ("The track's cov is not invertible, quit updating.");
95 return &vtx;
96 }
97
98 const int sign = (mode == IVertexUpdator::addTrack ? 1 : -1);
99 chi2 += sign * (vertexPositionChi2(vtx, fit_vrt) + trkWeight * trk_chi);
100
101 //number of degrees of freedom
102 double ndf = vtx.numberDoF();
103 ndf += sign * trkWeight * (2.0);
104
105 //forming a final xAOD::Vertex
106 vtx.setPosition( fit_vrt.position );
107 vtx.setCovariancePosition( fit_vrt.covariancePosition );
108 vtx.setFitQuality( chi2, ndf );
109
110 //playing with vector of fitted tracks and compatibility
111 if( mode == IVertexUpdator::addTrack )
112 {
113 //changes towards fit quality
114 righttrack->setWeight( trkWeight );
115 righttrack->setTrackQuality( Trk::FitQuality(trk_chi, 2 * trkWeight) );
116 }
117 else
118 {
119 tracksAtVertex.erase( righttrack );
120 }
121
122 return &vtx;
123 }//end of update method
124
125 //actual method where the position update happens
127 {
128 // linearized track information
129 const AmgMatrix(5,3)& A = trk->positionJacobian();
130 const AmgMatrix(5,3)& B = trk->momentumJacobian();
131 const AmgVector(5) & trackParameters = trk->expectedParametersAtPCA();
132 const AmgVector(5) & constantTerm = trk->constantTerm();
133 const AmgSymMatrix(5) & trackParametersWeight = trk->expectedWeightAtPCA();
134
135 int sign = (mode == IVertexUpdator::addTrack ? 1 : -1);
136
137 //vertex to be updated
138 const Amg::Vector3D & old_pos = vtx.position();
139 const AmgSymMatrix(3)& old_vrt_weight = vtx.covariancePosition().inverse();
140 ATH_MSG_VERBOSE ("Old vertex weight " << old_vrt_weight);
141
142 //making the intermediate quantities:
143 //W_k = (B^T*G*B)^(-1)
144
145 AmgSymMatrix(3) S = B.transpose()*(trackParametersWeight*B);
146 S = S.inverse().eval();
147
148 //G_b = G_k - G_k*B_k*W_k*B_k^(T)*G_k
149 AmgSymMatrix(5) gB = trackParametersWeight - trackParametersWeight*(B*(S*B.transpose()))*trackParametersWeight.transpose();
150
151 //new vertex weight matrix
152 AmgSymMatrix(3) new_vrt_weight_later_cov = old_vrt_weight + trackWeight * sign * A.transpose()*(gB*A);
153
154 new_vrt_weight_later_cov = new_vrt_weight_later_cov.inverse().eval();
155
156 //new vertex position
157 Amg::Vector3D new_vrt_position = new_vrt_weight_later_cov*(old_vrt_weight * old_pos + trackWeight * sign * A.transpose() * gB *(trackParameters - constantTerm) );
158
159 return IVertexUpdator::positionUpdateOutcome{new_vrt_position, new_vrt_weight_later_cov,trackParametersWeight};
160 }//end of position update method
161
162
163 //xAOD chi2 increment method
165 {
166 return trackParametersChi2(new_vtx.position(), trk, trk->expectedWeightAtPCA());
167 }//end of chi2 increment method
168
169 float KalmanVertexUpdator::vertexPositionChi2(const xAOD::Vertex& old_vtx, const xAOD::Vertex& new_vtx) const
170 {
171 return vertexPositionChi2(old_vtx, new_vtx.position());
172 }//end of vertex position chi2
173
174
175 float KalmanVertexUpdator::trackParametersChi2(const Amg::Vector3D & new_position, const LinearizedTrack * trk,const AmgSymMatrix(5) & trkParametersWeight) {
176
177 // track information
178 const AmgMatrix(5,3)& A = trk->positionJacobian();
179 const AmgMatrix(5,3) & B = trk->momentumJacobian();
180 const AmgVector(5) & trkParameters = trk->expectedParametersAtPCA();
181
182 //calculation of S matrix
183 AmgSymMatrix(3) Sm = B.transpose()*(trkParametersWeight*B);
184 AmgSymMatrix(3) Sm_inverse;
185 bool invertible;
186 Sm.computeInverseWithCheck(Sm_inverse,invertible);
187 if(!invertible) {
188 return -999.;
189 }
190 Sm= Sm_inverse.eval();
191
192 const AmgVector(5)& theResidual = trk->constantTerm();
193
194 //refitted track momentum
195 Amg::Vector3D newTrackMomentum = Sm*B.transpose()*trkParametersWeight*(trkParameters - theResidual - A*new_position);
196
197 //refitted track parameters
198 AmgVector(5) refTrackParameters = theResidual + A * new_position + B * newTrackMomentum;
199
200 //parameters difference
201 AmgVector(5) paramDifference = trkParameters - refTrackParameters;
202
203 return paramDifference.transpose() * ( trkParametersWeight * paramDifference );;
204
205 }
206 float KalmanVertexUpdator::vertexPositionChi2(const xAOD::Vertex& old_vtx, const Amg::Vector3D & new_position) {
207 AmgSymMatrix(3) old_wrt_weight = old_vtx.covariancePosition().inverse();
208 Amg::Vector3D posDifference = new_position - old_vtx.position();
209 return posDifference.transpose()*(old_wrt_weight*posDifference);
210 }
211
213 return trackParametersChi2(new_vtx.position, trk, new_vtx.trkParametersWeight);
214 }//end of chi2 increment method
215
217 return vertexPositionChi2(old_vtx, new_vtx.position);
218 }//end of vertex position chi2
219
220}//end of namespace definition
#define endmsg
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define AmgSymMatrix(dim)
#define AmgVector(rows)
#define AmgMatrix(rows, cols)
static Double_t sc
int sign(int a)
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
MsgStream & msg() const
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
Definition FitQuality.h:97
KalmanVertexUpdator(const std::string &t, const std::string &n, const IInterface *p)
Constructor.
xAOD::Vertex * update(xAOD::Vertex &vtx, const VxTrackAtVertex &trk, IVertexUpdator::updateMode mode) const
Method where the fit is actually done.
virtual float vertexPositionChi2(const xAOD::Vertex &old_vtx, const xAOD::Vertex &new_vtx) const override
Method calculating the vertex displacement-related part of the chi2.
virtual xAOD::Vertex * add(xAOD::Vertex &vtx, VxTrackAtVertex &trk) const override
Method adding a single track to the vertex estimate.
virtual IVertexUpdator::positionUpdateOutcome positionUpdate(const xAOD::Vertex &vtx, const LinearizedTrack *trk, double trackWeight, IVertexUpdator::updateMode mode) const override
Position update method.
~KalmanVertexUpdator()
Destructor.
virtual StatusCode initialize() override
virtual xAOD::Vertex * remove(xAOD::Vertex &vtx, VxTrackAtVertex &trk) const override
Method removing already added track from the vertex estimate.
virtual float trackParametersChi2(const xAOD::Vertex &new_vtx, const LinearizedTrack *trk) const override
Method calculating the interstep Chi2 increment.
The VxTrackAtVertex is a common class for all present TrkVertexFitters The VxTrackAtVertex is designe...
LinearizedTrack * linState(void)
Access method for the perigee linearized track.
double weight(void) const
Information about the weight of track in fit (given back by annealing): weight=ndf/2.
void setCovariancePosition(const AmgSymMatrix(3)&covariancePosition)
Sets the vertex covariance matrix.
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.
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.
double chi2(TH1 *h0, TH1 *h1)
Eigen::Matrix< double, 3, 1 > Vector3D
Ensure that the ATLAS eigen extensions are properly loaded.
Vertex_v1 Vertex
Define the latest version of the vertex class.
hold the test vectors and ease the comparison