19 int numRow(
int numVertex) {
27 m_initialMomentumError(1000.)
29 declareInterface<KalmanVertexOnJetAxisUpdator>(
this);
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,
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);
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 );
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();
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");
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 = finalWeight;
631 if (new_vrt_weight.determinant()<=0) {
632 ATH_MSG_DEBUG(
"smartInvert() new_vrt_weight FINAL det. is: " << new_vrt_weight.determinant());