ATLAS Offline Software
Loading...
Searching...
No Matches
Trk::KalmanVertexOnJetAxisUpdator Class Reference

ATLAS Reconstruction Software - (C) 2005 - 2007. More...

#include <KalmanVertexOnJetAxisUpdator.h>

Inheritance diagram for Trk::KalmanVertexOnJetAxisUpdator:
Collaboration diagram for Trk::KalmanVertexOnJetAxisUpdator:

Public Member Functions

virtual StatusCode initialize () override
 KalmanVertexOnJetAxisUpdator (const std::string &t, const std::string &n, const IInterface *p)
 Constructor.
void add (VxTrackAtVertex *trackToAdd, const VxVertexOnJetAxis *vertexToUpdate, VxJetCandidate *candidateToUpdate) const
 Method updating the fit along the flight axis (VxJetCandidate) with a track (VxTrackOnJetAxis) which is added to the vertex along the jet axis provided (VxVertexOnJetAxis).
void addWithFastUpdate (VxTrackAtVertex *trackToAdd, const VxVertexOnJetAxis *vertexToUpdate, VxJetCandidate *candidateToUpdate) const
void remove (VxTrackAtVertex *trackToRemove, const VxVertexOnJetAxis *vertexToUpdate, VxJetCandidate *candidateToUpdate) const
 Method removing already added track from the fit along the flight axis, where you specify from what vertex along the jet axis the track should be removed.
void removeWithFastUpdate (VxTrackAtVertex *trackToRemove, const VxVertexOnJetAxis *vertexToUpdate, VxJetCandidate *candidateToUpdate) const
void updateChi2NdfInfo (VxTrackAtVertex *trackToUpdate, const VxVertexOnJetAxis *vertexToUpdate, VxJetCandidate *vertexCandidate) const
 Obsolete (will be removed - not in use, however migrated to eigen before finding out -WL) Updates only the chi2 + ndf information, in case the weight matrix is not inverted at every step, so that there is no info about the fitted position at intermediate steps of the fit.
void updateVertexChi2 (VxJetCandidate *vertexCandidate) const
 Obsolete (will be removed - not in use, however moved to eigen before finding out -WL).
Trk::RecVertexPositions positionUpdate (VxJetCandidate &vertexCandidate, const LinearizedTrack *trk, double trackWeight, int sign, int numVertex, bool isPrimary, bool doFastUpdate) const
 Method to do the Kalman Update of the positions of the fit along the flight axis with a single new track (which belongs to the VxVertexOnJetAxis number numVertex).
std::pair< Amg::Vector3D, Eigen::Matrix3Xd > createTransformJacobian (const Amg::VectorX &initialjetdir, int numVertex, bool isPrimary, bool truncate) const
 Method to create the Jacobian needed to go to the space of single vertices to the space of the variables representing the full fit along the flight axis (primary vertex, phi and theta of jet direction, distance to primary vertex of the remaining vertices along the jetaxis).
void smartInvert (Amg::MatrixX &new_vrt_cov) const
ServiceHandle< StoreGateSvc > & evtStore ()
 The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
const ServiceHandle< StoreGateSvc > & detStore () const
 The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
virtual StatusCode sysInitialize () override
 Perform system initialization for an algorithm.
virtual StatusCode sysStart () override
 Handle START transition.
virtual std::vector< Gaudi::DataHandle * > inputHandles () const override
 Return this algorithm's input handles.
virtual std::vector< Gaudi::DataHandle * > outputHandles () const override
 Return this algorithm's output handles.
Gaudi::Details::PropertyBase & declareProperty (Gaudi::Property< T, V, H > &t)
void updateVHKA (Gaudi::Details::PropertyBase &)
MsgStream & msg () const
bool msgLvl (const MSG::Level lvl) const

Static Public Member Functions

static const InterfaceID & interfaceID ()

Protected Member Functions

void renounceArray (SG::VarHandleKeyArray &handlesArray)
 remove all handles from I/O resolution
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce (T &h)
void extraDeps_update_handler (Gaudi::Details::PropertyBase &ExtraDeps)
 Add StoreName to extra input/output deps as needed.

Private Types

typedef ServiceHandle< StoreGateSvcStoreGateSvc_t

Private Member Functions

void update (VxTrackAtVertex *trackToUpdate, const VxVertexOnJetAxis *vertexToUpdate, VxJetCandidate *candidateToUpdate, int sign, bool doFastUpdate) const
 Internal method to do the Kalman Update.
double calculateTrackChi2 (const VxJetCandidate &vertexCandidate, const LinearizedTrack *trk, double trackWeight, int numVertex, bool isPrimary=false) const
 Internal method where the chi2/ndf update is actually done.
Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
 specialization for handling Gaudi::Property<SG::VarHandleKey>

Private Attributes

double m_initialMomentumError
StoreGateSvc_t m_evtStore
 Pointer to StoreGate (event store by default)
StoreGateSvc_t m_detStore
 Pointer to StoreGate (detector store by default)
std::vector< SG::VarHandleKeyArray * > m_vhka
bool m_varHandleArraysDeclared

Detailed Description

ATLAS Reconstruction Software - (C) 2005 - 2007.

Author
Giacinto Piacquadio, (giaci.nosp@m.nto..nosp@m.piacq.nosp@m.uadi.nosp@m.o@phy.nosp@m.sik..nosp@m.uni-f.nosp@m.reib.nosp@m.urg.d.nosp@m.e)
Christian Weiser, (chris.nosp@m.tian.nosp@m..weis.nosp@m.er@p.nosp@m.hysik.nosp@m..uni.nosp@m.-frei.nosp@m.burg.nosp@m..de)

A concrete implementation of the Vertex Updator using the Kalman filter algorithm.

This is a special implementation (part of the JetFitter algorithm) which is able to fit a vertex correcting the jet axis parameters to find the best overall agreement.

Basic approach is based on R. Fruhwirth et al. Comp. Phys. Comm 96(1996) 189

The first version implemented in TrkVertexFitterUtils, for general vertexing purposes, was created by Kirill Prokofiev and G.P.

First version: December 2006 Updated version for athena: Februar 2007

Alberts-Ludwig-Universita"t Freiburg

Definition at line 54 of file KalmanVertexOnJetAxisUpdator.h.

Member Typedef Documentation

◆ StoreGateSvc_t

typedef ServiceHandle<StoreGateSvc> AthCommonDataStore< AthCommonMsg< AlgTool > >::StoreGateSvc_t
privateinherited

Definition at line 388 of file AthCommonDataStore.h.

Constructor & Destructor Documentation

◆ KalmanVertexOnJetAxisUpdator()

Trk::KalmanVertexOnJetAxisUpdator::KalmanVertexOnJetAxisUpdator ( const std::string & t,
const std::string & n,
const IInterface * p )

Constructor.

Definition at line 25 of file KalmanVertexOnJetAxisUpdator.cxx.

25 :
26 AthAlgTool(t,n,p),
28 {
29 declareInterface<KalmanVertexOnJetAxisUpdator>(this);
30 declareProperty("initialMomentumError",m_initialMomentumError);
31 }
AthAlgTool()
Default constructor:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)

Member Function Documentation

◆ add()

void Trk::KalmanVertexOnJetAxisUpdator::add ( VxTrackAtVertex * trackToAdd,
const VxVertexOnJetAxis * vertexToUpdate,
VxJetCandidate * candidateToUpdate ) const

Method updating the fit along the flight axis (VxJetCandidate) with a track (VxTrackOnJetAxis) which is added to the vertex along the jet axis provided (VxVertexOnJetAxis).

To update the fit with a new vertex (VxVertexOnJetAxis) you have to iteratively add all its tracks to the fit using this method. In the RecVertexPositions datamember of the VxJetCandidate the result will appear as the value of the distance of this fitted vertex from the primary vertex. All the other vertices and the jet direction will of course be also dynamically adjusted while adding tracks to the fit.

Definition at line 45 of file KalmanVertexOnJetAxisUpdator.cxx.

47 {
48 update(trackToAdd,vertexToUpdate,candidateToUpdate,1,false);
49 }
void update(VxTrackAtVertex *trackToUpdate, const VxVertexOnJetAxis *vertexToUpdate, VxJetCandidate *candidateToUpdate, int sign, bool doFastUpdate) const
Internal method to do the Kalman Update.

◆ addWithFastUpdate()

void Trk::KalmanVertexOnJetAxisUpdator::addWithFastUpdate ( VxTrackAtVertex * trackToAdd,
const VxVertexOnJetAxis * vertexToUpdate,
VxJetCandidate * candidateToUpdate ) const

Definition at line 52 of file KalmanVertexOnJetAxisUpdator.cxx.

54 {
55 update(trackToAdd,vertexToUpdate,candidateToUpdate,1,true);
56 }

◆ calculateTrackChi2()

double Trk::KalmanVertexOnJetAxisUpdator::calculateTrackChi2 ( const VxJetCandidate & vertexCandidate,
const LinearizedTrack * trk,
double trackWeight,
int numVertex,
bool isPrimary = false ) const
private

Internal method where the chi2/ndf update is actually done.

Definition at line 429 of file KalmanVertexOnJetAxisUpdator.cxx.

432 {
433
434
435 //linearized track information
436 const VertexPositions & linearizationPositions = vertexCandidate.getLinearizationVertexPositions();
437 const Amg::VectorX & initialjetdir = linearizationPositions.position();
438
439 //calculate 3-dim position on jet axis from linearizationPositionVector and calculate Jacobian of transformation
440 std::pair<Amg::Vector3D,Eigen::Matrix3Xd> PosOnJetAxisAndTransformMatrix =
441 createTransformJacobian(initialjetdir, numVertex, isPrimary, true);
442
443 //only position jacobian changed from A ->oldA
444 const AmgMatrix(5,3)& oldA = trk->positionJacobian();
445
446 //now create the new jacobian which you should use
447 Eigen::Matrix<double,5,Eigen::Dynamic> A=oldA*PosOnJetAxisAndTransformMatrix.second;
448
449 const AmgMatrix(5,3)& B = trk->momentumJacobian();
450 const AmgVector(5) & trackParameters = trk->expectedParametersAtPCA();
451
452 AmgVector(5) constantTerm = trk->constantTerm() + oldA*PosOnJetAxisAndTransformMatrix.first
453 -A*initialjetdir;
454
455 const AmgSymMatrix(5) & trackParametersWeight = trk->expectedWeightAtPCA();
456
457 const RecVertexPositions & myPosition = vertexCandidate.getRecVertexPositions();
458 const Amg::VectorX & new_vrt_position = myPosition.position();
459
460 AmgSymMatrix(3) S = B.transpose()*trackParametersWeight*B;
461 if (S.determinant() == 0.0) {
462 ATH_MSG_WARNING ("The matrix S is not invertible, return chi2 0");
463 return -0.;
464 }
465 S = S.inverse().eval();
466
467 //refitted track momentum
468 Amg::Vector3D newTrackMomentum = S*B.transpose()*trackParametersWeight*(trackParameters - constantTerm - A*new_vrt_position);
469
470 //refitted track parameters
471 AmgVector(5) refTrackParameters = constantTerm + A * new_vrt_position + B * newTrackMomentum;
472
473 //parameters difference
474 AmgVector(5) paramDifference = trackParameters - refTrackParameters;
475
476 return (paramDifference.transpose()*trackParametersWeight*paramDifference)(0,0)*trackWeight;
477
478 }
#define ATH_MSG_WARNING(x)
#define AmgSymMatrix(dim)
#define AmgVector(rows)
#define AmgMatrix(rows, cols)
if(febId1==febId2)
std::pair< Amg::Vector3D, Eigen::Matrix3Xd > createTransformJacobian(const Amg::VectorX &initialjetdir, int numVertex, bool isPrimary, bool truncate) const
Method to create the Jacobian needed to go to the space of single vertices to the space of the variab...
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.

◆ createTransformJacobian()

std::pair< Amg::Vector3D, Eigen::Matrix3Xd > Trk::KalmanVertexOnJetAxisUpdator::createTransformJacobian ( const Amg::VectorX & initialjetdir,
int numVertex,
bool isPrimary,
bool truncate ) const

Method to create the Jacobian needed to go to the space of single vertices to the space of the variables representing the full fit along the flight axis (primary vertex, phi and theta of jet direction, distance to primary vertex of the remaining vertices along the jetaxis).

As a result the vector of position where the linearization was done and the jacobian are provided.

If the parameter truncate is true, the method also cuts the size of the matrix down to the only needed elements (if you work on vertex number 5, all the ones which come after are cut out from the jacobian to make the fit faster).

Definition at line 515 of file KalmanVertexOnJetAxisUpdator.cxx.

518 {
519
520 //now modify the position jacobian in the way you need!
521 const unsigned int numrow_toupdate = isPrimary ? 4: numRow(numVertex);
522 const unsigned int matrixdim = truncateDimensions ?
523 numrow_toupdate+1 :
524 initialjetdir.rows();
525
526 //store values of RecVertexOnJetAxis
527 double xv = initialjetdir[Trk::jet_xv];
528 double yv = initialjetdir[Trk::jet_yv];
529 double zv = initialjetdir[Trk::jet_zv];
530 double phi = initialjetdir[Trk::jet_phi];
531 double theta = initialjetdir[Trk::jet_theta];
532 double dist = 0;
533 if (!isPrimary) {
534 dist = initialjetdir[numrow_toupdate];
535 }
536
537 ATH_MSG_VERBOSE ("actual initialjetdir values : xv " << xv << " yv " << yv << " zv " << zv << " phi " << phi << " theta " << theta << " dist " << dist);
538 ATH_MSG_VERBOSE ("numrow_toupdate " << numrow_toupdate << " when primary it's -5");
539
540 //now create matrix transformation to go from vertex position jacobian to vertex in jet jacobian
541 //(essentially Jacobian of spherical coordinate system transformation)
542 Eigen::Matrix3Xd transform(3,matrixdim);
543 transform.setZero();
544 transform(0,Trk::jet_xv) = 1;
545 transform(1,Trk::jet_yv) = 1;
546 transform(2,Trk::jet_zv) = 1;
547 if (!isPrimary) {
548 transform(0,Trk::jet_phi) = -dist*sin(theta)*sin(phi);
550 transform(0,numrow_toupdate)= sin(theta)*cos(phi);
553 transform(1,numrow_toupdate)= sin(theta)*sin(phi);
554 transform(2,Trk::jet_theta) = -dist*sin(theta);
555 transform(2,numrow_toupdate)= cos(theta);
556 }
557
558 ATH_MSG_DEBUG ("The transform matrix xyzphitheta is: " << transform);
559
560 Amg::Vector3D posOnJetAxis;
561 posOnJetAxis(0) = xv+dist*cos(phi)*sin(theta);
562 posOnJetAxis(1) = yv+dist*sin(phi)*sin(theta);
563 posOnJetAxis(2) = zv+dist*cos(theta);
564
565 ATH_MSG_DEBUG("the lin position on jet axis x " << xv+dist*cos(phi)*sin(theta) << " y " << yv+dist*sin(phi)*sin(theta) << " z " << zv+dist*cos(theta));
566
567 return std::pair<Amg::Vector3D,Eigen::Matrix3Xd>(posOnJetAxis,transform);
568 }
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
@ theta
Definition ParamDefs.h:66
@ phi
Definition ParamDefs.h:75
@ jet_zv
position x,y,z of primary vertex
@ isPrimary
true if matched track has a hit in first or second pixel layer

◆ declareGaudiProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > & hndl,
const SG::VarHandleKeyType &  )
inlineprivateinherited

specialization for handling Gaudi::Property<SG::VarHandleKey>

Definition at line 156 of file AthCommonDataStore.h.

158 {
160 hndl.value(),
161 hndl.documentation());
162
163 }

◆ declareProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( Gaudi::Property< T, V, H > & t)
inlineinherited

Definition at line 145 of file AthCommonDataStore.h.

145 {
146 typedef typename SG::HandleClassifier<T>::type htype;
148 }
Gaudi::Details::PropertyBase & declareGaudiProperty(Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
specialization for handling Gaudi::Property<SG::VarHandleKey>

◆ detStore()

const ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore ( ) const
inlineinherited

The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 95 of file AthCommonDataStore.h.

◆ evtStore()

ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore ( )
inlineinherited

The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 85 of file AthCommonDataStore.h.

◆ extraDeps_update_handler()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::extraDeps_update_handler ( Gaudi::Details::PropertyBase & ExtraDeps)
protectedinherited

Add StoreName to extra input/output deps as needed.

use the logic of the VarHandleKey to parse the DataObjID keys supplied via the ExtraInputs and ExtraOuputs Properties to add the StoreName if it's not explicitly given

◆ initialize()

StatusCode Trk::KalmanVertexOnJetAxisUpdator::initialize ( )
overridevirtual

Definition at line 34 of file KalmanVertexOnJetAxisUpdator.cxx.

35 {
36 StatusCode sc = AthAlgTool::initialize();
37 if(sc.isFailure()){
38 ATH_MSG_ERROR (" Unable to initialize the AlgTool");
39 return StatusCode::FAILURE;
40 }
41 return StatusCode::SUCCESS;
42 }
#define ATH_MSG_ERROR(x)
static Double_t sc
::StatusCode StatusCode
StatusCode definition for legacy code.

◆ inputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< AlgTool > >::inputHandles ( ) const
overridevirtualinherited

Return this algorithm's input handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ interfaceID()

const InterfaceID & Trk::KalmanVertexOnJetAxisUpdator::interfaceID ( )
inlinestatic

Definition at line 58 of file KalmanVertexOnJetAxisUpdator.h.

59 {
61 };
static const InterfaceID IID_KalmanVertexOnJetAxisUpdator("Trk::KalmanVertexOnJetAxisUpdator", 1, 0)

◆ msg()

MsgStream & AthCommonMsg< AlgTool >::msg ( ) const
inlineinherited

Definition at line 24 of file AthCommonMsg.h.

24 {
25 return this->msgStream();
26 }

◆ msgLvl()

bool AthCommonMsg< AlgTool >::msgLvl ( const MSG::Level lvl) const
inlineinherited

Definition at line 30 of file AthCommonMsg.h.

30 {
31 return this->msgLevel(lvl);
32 }

◆ outputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< AlgTool > >::outputHandles ( ) const
overridevirtualinherited

Return this algorithm's output handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ positionUpdate()

Trk::RecVertexPositions Trk::KalmanVertexOnJetAxisUpdator::positionUpdate ( VxJetCandidate & vertexCandidate,
const LinearizedTrack * trk,
double trackWeight,
int sign,
int numVertex,
bool isPrimary,
bool doFastUpdate ) const

Method to do the Kalman Update of the positions of the fit along the flight axis with a single new track (which belongs to the VxVertexOnJetAxis number numVertex).

Definition at line 140 of file KalmanVertexOnJetAxisUpdator.cxx.

144 {
145
146 //linearized track information
147
148 const int numrow_toupdate = isPrimary ? 4 : numRow(numVertex);
149
150 const VertexPositions & linearizationPositions = candidateToUpdate.getLinearizationVertexPositions();
151
152 const Amg::VectorX & initialjetdir = linearizationPositions.position();
153
154 //calculate 3-dim position on jet axis from linearizationPositionVector and calculate Jacobian of transformation
155 std::pair<Amg::Vector3D,Eigen::Matrix3Xd> PosOnJetAxisAndTransformMatrix =
156 createTransformJacobian(initialjetdir, numVertex, isPrimary,
157 /*truncate=*/ !doFastUpdate); // original fast updator didn't have feature
158
159 //only position jacobian changed from A ->oldA
160 const AmgMatrix(5,3)& oldA = trk->positionJacobian();
161
162 ATH_MSG_DEBUG("the old jacobian xyz d0z0phithetaqoverp vs xyz " << oldA);
163
164 //now create the new jacobian which you should use
165 Eigen::Matrix<double,5,Eigen::Dynamic> A = oldA*PosOnJetAxisAndTransformMatrix.second;
166
167 ATH_MSG_DEBUG("the new jacobian " << A);
168
169 const AmgMatrix(5,3)& B = trk->momentumJacobian();
170 const AmgVector(5)& trackParameters = trk->expectedParametersAtPCA();
171
172 // the constant term has to be recalculated because of the use of the new parameters
173
174 const AmgVector(5) constantTerm = trk->constantTerm()
175 + oldA*PosOnJetAxisAndTransformMatrix.first
176 - A*initialjetdir.segment(0,numrow_toupdate+1);
177
178 //vertex to be updated, needs to be copied
179 RecVertexPositions myPosition = candidateToUpdate.getRecVertexPositions();
180
181 if (doFastUpdate) {
182
183 const AmgSymMatrix(5)& trackParametersCovariance = trk->expectedCovarianceAtPCA();
184
185 // old jetvertex in covariance formalism
186 const Amg::VectorX & old_vrt_pos = myPosition.position();
187 const Amg::MatrixX & old_vrt_cov = myPosition.covariancePosition();
188
189 //now create three additional variables for the momenta error
190 // (which is nearly infinite... use a big number here... then pay attention to numerical instabilities...)
191 AmgSymMatrix(3) old_vrt_cov_momentum; old_vrt_cov_momentum.setZero();
192 old_vrt_cov_momentum(0,0) = m_initialMomentumError*m_initialMomentumError;
193 old_vrt_cov_momentum(1,1) = m_initialMomentumError*m_initialMomentumError;
194 old_vrt_cov_momentum(2,2) = m_initialMomentumError*m_initialMomentumError/10000.;
195
196 //R_k_k-1 = V_k + A C_k-1 A_T + B D_k-1 B_T
197 AmgSymMatrix(5) old_residual_cov =
198 trackParametersCovariance + A * old_vrt_cov * A.transpose() +
199 B * old_vrt_cov_momentum * B.transpose();
200
201 //the nice thing of the method is that the matrix to invert (old_residual) is just 5x5,
202 //which is much better than n.track+5 x n.track+5 !!!
203 if (old_residual_cov.determinant() == 0. ) {
204 ATH_MSG_WARNING ("The old_residual matrix inversion failed");
205 ATH_MSG_WARNING ("same vertex as before is returned");
206 return Trk::RecVertexPositions(myPosition);
207 }
208
209 AmgSymMatrix(5) old_residual_cov_inv = old_residual_cov.inverse().eval();
210
211 Eigen::Matrix<double,Eigen::Dynamic,5> Kk1 = old_vrt_cov*A.transpose()*old_residual_cov_inv;
212 AmgVector(5) residual_vector=trackParameters-constantTerm-A*old_vrt_pos;
213
214 //obtain new position
215 Amg::VectorX new_vrt_pos=old_vrt_pos+Kk1*residual_vector;
216 Amg::MatrixX new_vrt_cov=old_vrt_cov+Kk1*old_residual_cov*Kk1.transpose()-2.*Kk1*A*old_vrt_cov;
217
218 double chi2 = myPosition.fitQuality().chiSquared() +
219 residual_vector.transpose()*old_residual_cov_inv*residual_vector;
220
221 //NOT SO NICE: BUT: if there was already a track at this vertex,
222 //then add 2, otherwise add 1 (additional parameter in the fit decreases +2 ndf)
223 double ndf=myPosition.fitQuality().numberDoF()+sign*2.;
224 return Trk::RecVertexPositions(new_vrt_pos,new_vrt_cov,ndf,chi2);
225 }
226
227 const AmgSymMatrix(5) & trackParametersWeight = trk->expectedWeightAtPCA();
228
229 if (trackParametersWeight.determinant()<=0) {
230 ATH_MSG_WARNING(" The determinant of the inverse of the track covariance matrix is negative: " << trackParametersWeight.determinant());
231 if(trk->expectedCovarianceAtPCA().determinant()<=0) {
232 ATH_MSG_WARNING(" As well as the determinant of the track covariance matrix: " << trk->expectedCovarianceAtPCA().determinant());
233 }
234 }
235
236 //vertex to be updated, needs to be copied
237 myPosition = candidateToUpdate.getRecVertexPositions();
238 const Amg::MatrixX & old_full_vrt_cov = myPosition.covariancePosition();
239 Eigen::FullPivLU<Amg::MatrixX> lu_decomp(old_full_vrt_cov);
240 if(!lu_decomp.isInvertible()){
241 ATH_MSG_DEBUG ("The vertex-positions covariance matrix is not invertible");
242 ATH_MSG_DEBUG ("The copy of initial vertex returned");
243 return Trk::RecVertexPositions(myPosition);
244 }
245
246 const Amg::VectorX & old_full_vrt_pos = myPosition.position();
247 Amg::VectorX old_vrt_pos = old_full_vrt_pos.segment(0,numrow_toupdate+1);
248
249 const Amg::MatrixX & old_full_vrt_weight = old_full_vrt_cov.inverse();
250
251 if (trackParametersWeight.determinant()<=0) {
252 ATH_MSG_WARNING(" The determinant of the track covariance matrix is zero or negative: " << trackParametersWeight.determinant());
253 }
254
255 Amg::MatrixX old_vrt_weight(numrow_toupdate+1,numrow_toupdate+1);
256 old_vrt_weight = old_full_vrt_weight.block(0,0,numrow_toupdate+1,numrow_toupdate+1);
257
258 //making the intermediate quantities:
259 //W_k = (B^T*G*B)^(-1)
260 AmgSymMatrix(3) S = B.transpose()*(trackParametersWeight*B);
261
262 if (S.determinant() == 0.0) {
263 ATH_MSG_WARNING ("The S matrix is not invertible");
264 ATH_MSG_WARNING ("A copy of initial vertex returned");
265 return Trk::RecVertexPositions(myPosition);
266 }
267 S = S.inverse().eval();
268
269 //G_b = G_k - G_k*B_k*W_k*B_k^(T)*G_k
270 AmgSymMatrix(5) gB = trackParametersWeight - trackParametersWeight*(B*(S*B.transpose()))*trackParametersWeight.transpose();
271
272 ATH_MSG_DEBUG("Gain factor obtained: "<<trackParametersWeight*(B*(S*B.transpose()))*trackParametersWeight.transpose());
273 ATH_MSG_DEBUG("Resulting Gain Matrix: "<<gB);
274
275 //new vertex weight matrix, called "cov" for later inversion
276 Amg::MatrixX new_vrt_cov = old_vrt_weight + trackWeight * sign * A.transpose() * ( gB * A );
277
278 if (sign<0) {
279 ATH_MSG_WARNING(" ATTENTION! Sign is " << sign);
280 }
281
282 if (new_vrt_cov.determinant()<=0) {
283 ATH_MSG_WARNING(std::scientific << "The new vtx weight matrix determinant is negative: "<< new_vrt_cov.determinant());
284 }
285
286 // now invert back to covariance
287 try {
288 // Temporarily remove smart inversion as it seems to cause negative errors from time to time
289 // Symmetrize the matix before inversion, to give ride of the precision problem of Eigen.
290 new_vrt_cov = (new_vrt_cov+new_vrt_cov.transpose().eval())/2.0;
291 smartInvert(new_vrt_cov);
292 if (new_vrt_cov.determinant() == 0.0) {
293 ATH_MSG_WARNING ("The reduced weight matrix is not invertible, returning copy of initial vertex.");
294 const Trk::RecVertexPositions& r_vtx(myPosition);
295 return r_vtx;
296 }
297 }
298
299 catch (std::string a) {
300 ATH_MSG_WARNING( a << " Previous vertex returned " );
301 const Trk::RecVertexPositions& r_vtx(myPosition);
302 return r_vtx;
303 }
304
305 ATH_MSG_DEBUG(" new vertex covariance " << new_vrt_cov);
306
307 if (new_vrt_cov.determinant()<=0) {
308 ATH_MSG_DEBUG("The new vtx cov. matrix determinant is negative: "<< new_vrt_cov.determinant());
309 }
310
311 //new vertex position
312 Amg::VectorX new_vrt_position =
313 new_vrt_cov*(old_vrt_weight * old_vrt_pos + trackWeight * sign * (A.transpose() * (gB *(trackParameters - constantTerm))));
314 ATH_MSG_DEBUG(" new position " << new_vrt_position);
315
316 //refitted track momentum
317 Amg::Vector3D newTrackMomentum = S*B.transpose()*trackParametersWeight*
318 (trackParameters - constantTerm - A*new_vrt_position);
319 ATH_MSG_DEBUG(" new momentum : " << newTrackMomentum);
320
321 //refitted track parameters
322 AmgVector(5) refTrackParameters = constantTerm + A * new_vrt_position + B * newTrackMomentum;
323
324 //parameters difference
325 AmgVector(5) paramDifference = trackParameters - refTrackParameters;
326 Amg::VectorX posDifference = new_vrt_position - old_vrt_pos;
327
328 double chi2 = myPosition.fitQuality().chiSquared()+
329 (paramDifference.transpose()*trackParametersWeight*paramDifference)(0,0)*trackWeight*sign+
330 (posDifference.transpose()*old_vrt_weight*posDifference)(0,0); // matrices are 1x1 but make scalar through (0,0)
331
332 ATH_MSG_DEBUG(" new chi2 : " << chi2);
333
334 //NOT SO NICE: BUT: if there was already a track at this vertex,
335 //then add 2, otherwise add 1 (additional parameter in the fit decreases +2 ndf)
336 double ndf=myPosition.fitQuality().numberDoF()+sign*2.;
337
338 for (int i=0; i<new_vrt_cov.rows(); i++){
339 bool negative(false);
340 if (new_vrt_cov(i,i)<=0.) {
341 ATH_MSG_WARNING(" Diagonal element ("<<i<<","<<i<<") of covariance matrix after update negative: "<<new_vrt_cov(i,i) <<". Giving back previous vertex.");
342 negative=true;
343 }
344 if (negative) {
345 const Trk::RecVertexPositions& r_vtx(myPosition);
346 return r_vtx;
347 }
348 }
349
350 Amg::VectorX new_full_vrt_pos(old_full_vrt_pos);
351 new_full_vrt_pos.segment(0,new_vrt_position.rows()) = new_vrt_position;
352 Amg::MatrixX new_full_vrt_cov(myPosition.covariancePosition());
353 new_full_vrt_cov.block(0,0,new_vrt_cov.rows(),new_vrt_cov.cols()) = new_vrt_cov;
354
355 Trk::RecVertexPositions r_vtx(new_full_vrt_pos,new_full_vrt_cov,ndf, chi2);
356 return r_vtx;
357
358 //method which avoids inverting huge covariance matrix still needs to be implemented
359
360 } //end of position update method
static Double_t a
int sign(int a)
void smartInvert(Amg::MatrixX &new_vrt_cov) const
double chi2(TH1 *h0, TH1 *h1)
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.

◆ remove()

void Trk::KalmanVertexOnJetAxisUpdator::remove ( VxTrackAtVertex * trackToRemove,
const VxVertexOnJetAxis * vertexToUpdate,
VxJetCandidate * candidateToUpdate ) const

Method removing already added track from the fit along the flight axis, where you specify from what vertex along the jet axis the track should be removed.

Usefull for smoothing and for estimating the compatibility of single vertices with the rest of the fit (the smoothed chi2 of the vertex can be obtained by iteratively removing all its tracks and storing the intermediate result at every time).

Just adding the chi2 of every track involved (as in Fruehwirth's reference) would lead here to misleading results.

Definition at line 59 of file KalmanVertexOnJetAxisUpdator.cxx.

61 {
62 update(trackToRemove,vertexToUpdate,candidateToUpdate,-1,false);
63 }

◆ removeWithFastUpdate()

void Trk::KalmanVertexOnJetAxisUpdator::removeWithFastUpdate ( VxTrackAtVertex * trackToRemove,
const VxVertexOnJetAxis * vertexToUpdate,
VxJetCandidate * candidateToUpdate ) const

Definition at line 66 of file KalmanVertexOnJetAxisUpdator.cxx.

68 {
69 update(trackToRemove,vertexToUpdate,candidateToUpdate,-1,true);
70 }

◆ renounce()

std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > AthCommonDataStore< AthCommonMsg< AlgTool > >::renounce ( T & h)
inlineprotectedinherited

Definition at line 380 of file AthCommonDataStore.h.

381 {
382 h.renounce();
384 }
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce(T &h)

◆ renounceArray()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::renounceArray ( SG::VarHandleKeyArray & handlesArray)
inlineprotectedinherited

remove all handles from I/O resolution

Definition at line 364 of file AthCommonDataStore.h.

364 {
366 }

◆ smartInvert()

void Trk::KalmanVertexOnJetAxisUpdator::smartInvert ( Amg::MatrixX & new_vrt_cov) const

Definition at line 571 of file KalmanVertexOnJetAxisUpdator.cxx.

572 {
573
574 int numRows = new_vrt_weight.rows();
575 if (numRows<=6) {
576 if (new_vrt_weight.determinant() ==0) {
577 throw std::string("The reduced weight matrix is not invertible. Previous vertex returned ");
578 }
579 new_vrt_weight = new_vrt_weight.inverse().eval();
580 return;
581 }
582
583 AmgSymMatrix(5) A = new_vrt_weight.block<5,5>(0,0);
584 //Eigen::Dynamic we are not sure about the number of Row minus 5, so a dynamic one is given here.
585 Eigen::Matrix<double,5,Eigen::Dynamic> B(5,numRows-5);
586 B.setZero();
587 for (int i=0; i<5; ++i) {
588 for (int j=5; j<numRows; ++j) {
589 B(i,j-5)=new_vrt_weight(i,j);
590 }
591 }
592
593 // will be of dim (numrows-5)
594 Amg::MatrixX D = new_vrt_weight.block(5,5,numRows-5,numRows-5);
595
596 // Eigen's diagonal matrices don't have the full MatrixBase members like determinant(),
597 // similarity() etc needed later -> therefore do not use them and invert by hand.
598 // The inverse of D is a diagonal matrix of the inverted diagonal elements -WL
599 // Eigen::DiagonalMatrix<double,Eigen::Dynamic> DdiagINV(D); do something...
600 for (unsigned int i=0; i<D.rows(); i++) {
601 if ( D(i,i) == 0.) {
602 throw std::string("Cannot invert diagonal matrix...");
603 break;
604 }
605
606 //Set the non-diagonal elements of D to be zero, which is as expected; the numerical proplem will change them into non-zero.
607 for(unsigned int j=0; j<i; j++){
608 D(i,j) = 0;
609 D(j,i) = 0;
610 }
611 D(i,i) = 1./D(i,i);
612 }
613
614 Amg::MatrixX E = A - B*(D*B.transpose());
615 if (E.determinant() == 0.) {
616 throw std::string("Cannot invert E matrix...");
617 }
618 E = E.inverse().eval();
619
620 Amg::MatrixX finalWeight(numRows,numRows);
621 finalWeight.setZero();
622 finalWeight.block<5,5>(0,0) = E;
623 Eigen::Matrix<double,5,Eigen::Dynamic> F = -E*(B*D);
624 finalWeight.block(0,5,5,D.rows()) = F;
625 finalWeight.block(5,0,D.rows(),5) = F.transpose();
626 finalWeight.block(5,5,D.rows(),D.rows()) =
627 D+(D*((B.transpose()*(E*B))*D.transpose()));
628
629 new_vrt_weight = finalWeight;
630
631 if (new_vrt_weight.determinant()<=0) {
632 ATH_MSG_DEBUG("smartInvert() new_vrt_weight FINAL det. is: " << new_vrt_weight.determinant());
633 }
634
635 }
#define F(x, y, z)
Definition MD5.cxx:112

◆ sysInitialize()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysInitialize ( )
overridevirtualinherited

Perform system initialization for an algorithm.

We override this to declare all the elements of handle key arrays at the end of initialization. See comments on updateVHKA.

Reimplemented in asg::AsgMetadataTool, AthCheckedComponent< AthAlgTool >, AthCheckedComponent<::AthAlgTool >, and DerivationFramework::CfAthAlgTool.

◆ sysStart()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysStart ( )
overridevirtualinherited

Handle START transition.

We override this in order to make sure that conditions handle keys can cache a pointer to the conditions container.

◆ update()

void Trk::KalmanVertexOnJetAxisUpdator::update ( VxTrackAtVertex * trackToUpdate,
const VxVertexOnJetAxis * vertexToUpdate,
VxJetCandidate * candidateToUpdate,
int sign,
bool doFastUpdate ) const
private

Internal method to do the Kalman Update.

This is where the real fit iteration is done.

Definition at line 73 of file KalmanVertexOnJetAxisUpdator.cxx.

76 {
77
78 //check that all pointers are there...
79 if (trackToUpdate==nullptr || vertexToUpdate==nullptr ||
80 candidateToUpdate==nullptr || std::abs(sign)!=1) {
81 ATH_MSG_WARNING (" Empty pointers then calling fit method update. No fit will be done...");
82 return;
83 }
84
85 //getting tracks at vertex and verify if your trackToUpdate is there
86 bool found = false;
87 const std::vector<Trk::VxTrackAtVertex*> & tracksAtVertex(vertexToUpdate->getTracksAtVertex());
88 for (const auto& track : tracksAtVertex){
89 if (track==nullptr) {
90 ATH_MSG_WARNING (" Empty pointer in vector of VxTrackAtVertex of the VxVertexOnJetAxis which is being fitted. No fit will be done...");
91 return;
92 }
93 if (track==trackToUpdate) {
94 found=true;
95 break;
96 }
97 }
98
99 if (!found) {
100 ATH_MSG_WARNING ("Track was not found in the VxVertexOnJetAxis's list. No fit will be done...");
101 return;
102 }
103
104 double trkWeight = trackToUpdate->weight();
105 ATH_MSG_VERBOSE ("Weight is: " << trkWeight);
106
107 const Trk::RecVertexPositions & old_vrt = candidateToUpdate->getRecVertexPositions();
108
109 if (trackToUpdate->linState()==nullptr) {
110 ATH_MSG_WARNING ("Linearized state not associated to track. Aborting fit... " << old_vrt);
111 return;
112 }
113
114 RecVertexPositions fit_vrt;
115 if (vertexToUpdate!=candidateToUpdate->getPrimaryVertex()) {
116 //if not in primary vertex, then special update
117 fit_vrt = positionUpdate(*candidateToUpdate, trackToUpdate->linState(),
118 trkWeight, sign,
119 vertexToUpdate->getNumVertex(), false,
120 doFastUpdate);
121 } else {
122 //if in primary vertex, use dist=0
123 fit_vrt = positionUpdate(*candidateToUpdate, trackToUpdate->linState(),
124 trkWeight, sign,
125 vertexToUpdate->getNumVertex(), true,
126 doFastUpdate);
127 }
128
129 //forming a final candidate
130 candidateToUpdate->setRecVertexPositions(fit_vrt);
131
132 trackToUpdate->setTrackQuality(FitQuality(fit_vrt.fitQuality().chiSquared()-old_vrt.fitQuality().chiSquared(), 2));
133
134
135 }//end of update method
double chiSquared() const
returns the of the overall track fit
Definition FitQuality.h:56
Trk::RecVertexPositions positionUpdate(VxJetCandidate &vertexCandidate, const LinearizedTrack *trk, double trackWeight, int sign, int numVertex, bool isPrimary, bool doFastUpdate) const
Method to do the Kalman Update of the positions of the fit along the flight axis with a single new tr...
const Trk::FitQuality & fitQuality() const
Fit quality access method.

◆ updateChi2NdfInfo()

void Trk::KalmanVertexOnJetAxisUpdator::updateChi2NdfInfo ( VxTrackAtVertex * trackToUpdate,
const VxVertexOnJetAxis * vertexToUpdate,
VxJetCandidate * vertexCandidate ) const

Obsolete (will be removed - not in use, however migrated to eigen before finding out -WL) Updates only the chi2 + ndf information, in case the weight matrix is not inverted at every step, so that there is no info about the fitted position at intermediate steps of the fit.

Dropped because the chi2 obtained is not reliable.

Definition at line 362 of file KalmanVertexOnJetAxisUpdator.cxx.

364 {
365
366 //check that all pointers are there...
367 if (vertexCandidate==nullptr || trackToUpdate==nullptr) {
368 ATH_MSG_WARNING( " Empty pointers then calling fit method updateChi2NdfInfo. No update will be done..." );
369 return;
370 }
371
372 //getting tracks at vertex and verify if your trackToUpdate is there
373 bool found = false;
374 const std::vector<Trk::VxTrackAtVertex*> & tracksAtVertex(vertexToUpdate->getTracksAtVertex());
375
376 for (const auto& track : tracksAtVertex) {
377 if (track==nullptr) {
378 ATH_MSG_WARNING( " Empty pointer in vector of VxTrackAtVertex of the VxVertexOnJetAxis whose chi2 is being updated. No update will be done..." );
379 return;
380 }
381 if (track==trackToUpdate) {
382 found=true;
383 break;
384 }
385 }
386
387 if (!found) {
388 ATH_MSG_WARNING( " Track was not found in the VxVertexOnJetAxis's list. No update will be done..." );
389 return;
390 }
391
392 double trkWeight = trackToUpdate->weight();
393 ATH_MSG_VERBOSE ("Weight is: " << trkWeight);
394
395 Trk::RecVertexPositions vertexPositions = vertexCandidate->getRecVertexPositions();
396
397 if (trackToUpdate->linState()==nullptr) {
398 ATH_MSG_WARNING( "Linearized state not associated to track. Aborting chi2 update... " << vertexPositions );
399 return;
400 }
401
402 double chi2(vertexPositions.fitQuality().chiSquared());
403 ATH_MSG_VERBOSE ("old chi2: " << chi2);
404
405 if (vertexToUpdate!=vertexCandidate->getPrimaryVertex()) {
406 //if not in primary vertex, then special update
407 chi2+=calculateTrackChi2(*vertexCandidate, trackToUpdate->linState(),
408 trkWeight,
409 vertexToUpdate->getNumVertex(), false);
410 } else {
411 chi2+=calculateTrackChi2(*vertexCandidate, trackToUpdate->linState(),
412 trkWeight,
413 vertexToUpdate->getNumVertex(), true);
414 }
415
416 vertexPositions.setFitQuality(FitQuality(chi2,vertexPositions.fitQuality().numberDoF()));
417
418 ATH_MSG_VERBOSE (" new chi2: " << chi2);
419
420
421 trackToUpdate->setTrackQuality(FitQuality(chi2-vertexPositions.fitQuality().chiSquared(),
422 trackToUpdate->trackQuality().numberDoF()));
423
424 vertexCandidate->setRecVertexPositions(vertexPositions);
425
426 }
int numberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as integer
Definition FitQuality.h:60
double calculateTrackChi2(const VxJetCandidate &vertexCandidate, const LinearizedTrack *trk, double trackWeight, int numVertex, bool isPrimary=false) const
Internal method where the chi2/ndf update is actually done.
void setFitQuality(const Trk::FitQuality &)

◆ updateVertexChi2()

void Trk::KalmanVertexOnJetAxisUpdator::updateVertexChi2 ( VxJetCandidate * vertexCandidate) const

Obsolete (will be removed - not in use, however moved to eigen before finding out -WL).

Updates the chi2/ndf of the entire fit with the final information about the position.

Definition at line 481 of file KalmanVertexOnJetAxisUpdator.cxx.

481 {
482
483 //check that all pointers are there...
484 if (vertexCandidate==nullptr) {
485 ATH_MSG_WARNING( " Empty pointers then calling chi2 update method updateVertexChi2. No update will be done..." );
486 return;
487 }
488
489 const Trk::RecVertexPositions & OldPosition = vertexCandidate->getConstraintVertexPositions();
490 const Amg::VectorX & old_vrt_position = OldPosition.position();
491 const Amg::MatrixX & old_vrt_weight = OldPosition.covariancePosition().inverse();
492
493 const RecVertexPositions & myPosition = vertexCandidate->getRecVertexPositions();
494 const Amg::VectorX & new_vrt_position = myPosition.position();
495
496 AmgVector(5) posDifference = (new_vrt_position - old_vrt_position).segment(0,5);
497
498 double chi2 = (posDifference.transpose()*old_vrt_weight.block<5,5>(0,0)*posDifference)(0,0);
499
500#ifdef Updator_DEBUG
501 std::cout << " vertex diff chi2 : " << chi2 << std::endl;
502#endif
503
504 Trk::RecVertexPositions vertexPositions = vertexCandidate->getRecVertexPositions();
505
506 vertexPositions.setFitQuality(FitQuality(vertexPositions.fitQuality().chiSquared()+chi2,
507 vertexPositions.fitQuality().numberDoF()));
508
509 vertexCandidate->setRecVertexPositions(vertexPositions);
510
511 }
Amg::MatrixX const & covariancePosition() const
return the covDeltaV matrix of the vertex fit
const Amg::VectorX & position() const
return position of vertex

◆ updateVHKA()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::updateVHKA ( Gaudi::Details::PropertyBase & )
inlineinherited

Definition at line 308 of file AthCommonDataStore.h.

308 {
309 // debug() << "updateVHKA for property " << p.name() << " " << p.toString()
310 // << " size: " << m_vhka.size() << endmsg;
311 for (auto &a : m_vhka) {
313 for (auto k : keys) {
314 k->setOwner(this);
315 }
316 }
317 }
std::vector< SG::VarHandleKeyArray * > m_vhka

Member Data Documentation

◆ m_detStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_detStore
privateinherited

Pointer to StoreGate (detector store by default)

Definition at line 393 of file AthCommonDataStore.h.

◆ m_evtStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_evtStore
privateinherited

Pointer to StoreGate (event store by default)

Definition at line 390 of file AthCommonDataStore.h.

◆ m_initialMomentumError

double Trk::KalmanVertexOnJetAxisUpdator::m_initialMomentumError
private

Definition at line 174 of file KalmanVertexOnJetAxisUpdator.h.

◆ m_varHandleArraysDeclared

bool AthCommonDataStore< AthCommonMsg< AlgTool > >::m_varHandleArraysDeclared
privateinherited

Definition at line 399 of file AthCommonDataStore.h.

◆ m_vhka

std::vector<SG::VarHandleKeyArray*> AthCommonDataStore< AthCommonMsg< AlgTool > >::m_vhka
privateinherited

Definition at line 398 of file AthCommonDataStore.h.


The documentation for this class was generated from the following files: