19 int numRow(
int numVertex) {
29 declareInterface<KalmanVertexOnJetAxisUpdator>(
this);
36 StatusCode
sc = AthAlgTool::initialize();
39 return StatusCode::FAILURE;
41 return StatusCode::SUCCESS;
48 update(trackToAdd,vertexToUpdate,candidateToUpdate,1,
false);
55 update(trackToAdd,vertexToUpdate,candidateToUpdate,1,
true);
62 update(trackToRemove,vertexToUpdate,candidateToUpdate,-1,
false);
69 update(trackToRemove,vertexToUpdate,candidateToUpdate,-1,
true);
76 int sign,
bool doFastUpdate)
const {
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...");
87 const std::vector<Trk::VxTrackAtVertex*> & tracksAtVertex(vertexToUpdate->
getTracksAtVertex());
88 for (
const auto& track : tracksAtVertex){
90 ATH_MSG_WARNING (
" Empty pointer in vector of VxTrackAtVertex of the VxVertexOnJetAxis which is being fitted. No fit will be done...");
93 if (track==trackToUpdate) {
100 ATH_MSG_WARNING (
"Track was not found in the VxVertexOnJetAxis's list. No fit will be done...");
104 double trkWeight = trackToUpdate->
weight();
109 if (trackToUpdate->
linState()==
nullptr) {
110 ATH_MSG_WARNING (
"Linearized state not associated to track. Aborting fit... " << old_vrt);
142 double trackWeight,
int sign,
143 int numVertex,
bool isPrimary,
144 bool doFastUpdate)
const {
148 const int numrow_toupdate = isPrimary ? 4 : numRow(numVertex);
155 std::pair<Amg::Vector3D,Eigen::Matrix3Xd> PosOnJetAxisAndTransformMatrix =
160 const AmgMatrix(5,3)& oldA = trk->positionJacobian();
162 ATH_MSG_DEBUG(
"the old jacobian xyz d0z0phithetaqoverp vs xyz " << oldA);
165 Eigen::Matrix<double,5,Eigen::Dynamic>
A = oldA*PosOnJetAxisAndTransformMatrix.second;
169 const AmgMatrix(5,3)& B = trk->momentumJacobian();
170 const AmgVector(5)& trackParameters = trk->expectedParametersAtPCA();
174 const AmgVector(5) constantTerm = trk->constantTerm()
175 + oldA*PosOnJetAxisAndTransformMatrix.first
176 -
A*initialjetdir.segment(0,numrow_toupdate+1);
183 const AmgSymMatrix(5)& trackParametersCovariance = trk->expectedCovarianceAtPCA();
191 AmgSymMatrix(3) old_vrt_cov_momentum; old_vrt_cov_momentum.setZero();
198 trackParametersCovariance +
A * old_vrt_cov *
A.transpose() +
199 B * old_vrt_cov_momentum * B.transpose();
203 if (old_residual_cov.determinant() == 0. ) {
209 AmgSymMatrix(5) old_residual_cov_inv = old_residual_cov.inverse().eval();
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;
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;
219 residual_vector.transpose()*old_residual_cov_inv*residual_vector;
227 const AmgSymMatrix(5) & trackParametersWeight = trk->expectedWeightAtPCA();
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());
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");
247 Amg::VectorX old_vrt_pos = old_full_vrt_pos.segment(0,numrow_toupdate+1);
249 const Amg::MatrixX & old_full_vrt_weight = old_full_vrt_cov.inverse();
251 if (trackParametersWeight.determinant()<=0) {
252 ATH_MSG_WARNING(
" The determinant of the track covariance matrix is zero or negative: " << trackParametersWeight.determinant());
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);
260 AmgSymMatrix(3) S = B.transpose()*(trackParametersWeight*B);
262 if (S.determinant() == 0.0) {
267 S = S.inverse().eval();
270 AmgSymMatrix(5) gB = trackParametersWeight - trackParametersWeight*(B*(S*B.transpose()))*trackParametersWeight.transpose();
272 ATH_MSG_DEBUG(
"Gain factor obtained: "<<trackParametersWeight*(B*(S*B.transpose()))*trackParametersWeight.transpose());
276 Amg::MatrixX new_vrt_cov = old_vrt_weight + trackWeight *
sign *
A.transpose() * ( gB *
A );
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());
290 new_vrt_cov = (new_vrt_cov+new_vrt_cov.transpose().eval())/2.0;
292 if (new_vrt_cov.determinant() == 0.0) {
293 ATH_MSG_WARNING (
"The reduced weight matrix is not invertible, returning copy of initial vertex.");
299 catch (std::string
a) {
307 if (new_vrt_cov.determinant()<=0) {
308 ATH_MSG_DEBUG(
"The new vtx cov. matrix determinant is negative: "<< new_vrt_cov.determinant());
313 new_vrt_cov*(old_vrt_weight * old_vrt_pos + trackWeight *
sign * (
A.transpose() * (gB *(trackParameters - constantTerm))));
317 Amg::Vector3D newTrackMomentum = S*B.transpose()*trackParametersWeight*
318 (trackParameters - constantTerm -
A*new_vrt_position);
322 AmgVector(5) refTrackParameters = constantTerm +
A * new_vrt_position + B * newTrackMomentum;
325 AmgVector(5) paramDifference = trackParameters - refTrackParameters;
326 Amg::VectorX posDifference = new_vrt_position - old_vrt_pos;
329 (paramDifference.transpose()*trackParametersWeight*paramDifference)(0,0)*trackWeight*
sign+
330 (posDifference.transpose()*old_vrt_weight*posDifference)(0,0);
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.");
351 new_full_vrt_pos.segment(0,new_vrt_position.rows()) = new_vrt_position;
353 new_full_vrt_cov.block(0,0,new_vrt_cov.rows(),new_vrt_cov.cols()) = new_vrt_cov;
367 if (vertexCandidate==
nullptr || trackToUpdate==
nullptr) {
368 ATH_MSG_WARNING(
" Empty pointers then calling fit method updateChi2NdfInfo. No update will be done..." );
374 const std::vector<Trk::VxTrackAtVertex*> & tracksAtVertex(vertexToUpdate->
getTracksAtVertex());
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..." );
381 if (track==trackToUpdate) {
388 ATH_MSG_WARNING(
" Track was not found in the VxVertexOnJetAxis's list. No update will be done..." );
392 double trkWeight = trackToUpdate->
weight();
397 if (trackToUpdate->
linState()==
nullptr) {
398 ATH_MSG_WARNING(
"Linearized state not associated to track. Aborting chi2 update... " << vertexPositions );
432 int numVertex,
bool isPrimary)
const {
440 std::pair<Amg::Vector3D,Eigen::Matrix3Xd> PosOnJetAxisAndTransformMatrix =
444 const AmgMatrix(5,3)& oldA = trk->positionJacobian();
447 Eigen::Matrix<double,5,Eigen::Dynamic>
A=oldA*PosOnJetAxisAndTransformMatrix.second;
449 const AmgMatrix(5,3)& B = trk->momentumJacobian();
450 const AmgVector(5) & trackParameters = trk->expectedParametersAtPCA();
452 AmgVector(5) constantTerm = trk->constantTerm() + oldA*PosOnJetAxisAndTransformMatrix.first
455 const AmgSymMatrix(5) & trackParametersWeight = trk->expectedWeightAtPCA();
460 AmgSymMatrix(3) S = B.transpose()*trackParametersWeight*B;
461 if (S.determinant() == 0.0) {
465 S = S.inverse().eval();
468 Amg::Vector3D newTrackMomentum = S*B.transpose()*trackParametersWeight*(trackParameters - constantTerm -
A*new_vrt_position);
471 AmgVector(5) refTrackParameters = constantTerm +
A * new_vrt_position + B * newTrackMomentum;
474 AmgVector(5) paramDifference = trackParameters - refTrackParameters;
476 return (paramDifference.transpose()*trackParametersWeight*paramDifference)(0,0)*trackWeight;
484 if (vertexCandidate==
nullptr) {
485 ATH_MSG_WARNING(
" Empty pointers then calling chi2 update method updateVertexChi2. No update will be done..." );
496 AmgVector(5) posDifference = (new_vrt_position - old_vrt_position).segment(0,5);
498 double chi2 = (posDifference.transpose()*old_vrt_weight.block<5,5>(0,0)*posDifference)(0,0);
501 std::cout <<
" vertex diff chi2 : " <<
chi2 << std::endl;
514 std::pair<Amg::Vector3D,Eigen::Matrix3Xd>
518 bool truncateDimensions)
const {
521 const unsigned int numrow_toupdate = isPrimary ? 4: numRow(numVertex);
522 const unsigned int matrixdim = truncateDimensions ?
524 initialjetdir.rows();
534 dist = initialjetdir[numrow_toupdate];
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");
542 Eigen::Matrix3Xd transform(3,matrixdim);
550 transform(0,numrow_toupdate)= sin(
theta)*cos(
phi);
553 transform(1,numrow_toupdate)= sin(
theta)*sin(
phi);
555 transform(2,numrow_toupdate)= cos(
theta);
558 ATH_MSG_DEBUG (
"The transform matrix xyzphitheta is: " << transform);
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);
567 return std::pair<Amg::Vector3D,Eigen::Matrix3Xd>(posOnJetAxis,transform);
574 int numRows = new_vrt_weight.rows();
576 if (new_vrt_weight.determinant() ==0) {
577 throw std::string(
"The reduced weight matrix is not invertible. Previous vertex returned ");
579 new_vrt_weight = new_vrt_weight.inverse().eval();
585 Eigen::Matrix<double,5,Eigen::Dynamic> B(5,numRows-5);
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);
594 Amg::MatrixX D = new_vrt_weight.block(5,5,numRows-5,numRows-5);
600 for (
unsigned int i=0; i<D.rows(); i++) {
602 throw std::string(
"Cannot invert diagonal matrix...");
607 for(
unsigned int j=0; j<i; j++){
615 if (E.determinant() == 0.) {
616 throw std::string(
"Cannot invert E matrix...");
618 E = E.inverse().eval();
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()));
629 new_vrt_weight = std::move(finalWeight);
631 if (new_vrt_weight.determinant()<=0) {
632 ATH_MSG_DEBUG(
"smartInvert() new_vrt_weight FINAL det. is: " << new_vrt_weight.determinant());
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define AmgSymMatrix(dim)
#define AmgMatrix(rows, cols)
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
int numberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as integer
double chiSquared() const
returns the of the overall track fit
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 onl...
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 v...
void add(VxTrackAtVertex *trackToAdd, const VxVertexOnJetAxis *vertexToUpdate, VxJetCandidate *candidateToUpdate) const
Method updating the fit along the flight axis (VxJetCandidate) with a track (VxTrackOnJetAxis) which ...
void updateVertexChi2(VxJetCandidate *vertexCandidate) const
Obsolete (will be removed - not in use, however moved to eigen before finding out -WL).
virtual StatusCode initialize() override
void smartInvert(Amg::MatrixX &new_vrt_cov) const
void removeWithFastUpdate(VxTrackAtVertex *trackToRemove, const VxVertexOnJetAxis *vertexToUpdate, VxJetCandidate *candidateToUpdate) const
double m_initialMomentumError
KalmanVertexOnJetAxisUpdator(const std::string &t, const std::string &n, const IInterface *p)
Constructor.
void update(VxTrackAtVertex *trackToUpdate, const VxVertexOnJetAxis *vertexToUpdate, VxJetCandidate *candidateToUpdate, int sign, bool doFastUpdate) const
Internal method to do the Kalman Update.
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...
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.
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...
Amg::MatrixX const & covariancePosition() const
return the covDeltaV matrix of the vertex fit
void setFitQuality(const Trk::FitQuality &)
const Trk::FitQuality & fitQuality() const
Fit quality access method.
VertexPositions class to represent and store a vertex.
const Amg::VectorX & position() const
return position of vertex
const Trk::VertexPositions & getLinearizationVertexPositions() const
const Trk::RecVertexPositions & getConstraintVertexPositions() const
const VxVertexOnJetAxis * getPrimaryVertex(void) const
const Trk::RecVertexPositions & getRecVertexPositions() const
void setRecVertexPositions(const Trk::RecVertexPositions &)
The VxTrackAtVertex is a common class for all present TrkVertexFitters The VxTrackAtVertex is designe...
void setTrackQuality(const FitQuality &trkQuality)
Set methods for various components.
LinearizedTrack * linState(void)
Access method for the perigee linearized track.
FitQuality trackQuality(void) const
Returns a pointer to the original track if any.
double weight(void) const
Information about the weight of track in fit (given back by annealing): weight=ndf/2.
VxVertexOnJetAxis inherits from Vertex.
int getNumVertex(void) const
Get Method for NumVertex.
const std::vector< VxTrackAtVertex * > & getTracksAtVertex(void) const
get Tracks At Vertex Method
double chi2(TH1 *h0, TH1 *h1)
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
Ensure that the ATLAS eigen extensions are properly loaded.
@ jet_zv
position x,y,z of primary vertex
hold the test vectors and ease the comparison