ATLAS Offline Software
KalmanVertexOnJetAxisUpdator.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
12 #include <algorithm>
13 #include <utility>
14 
15 
16 namespace Trk{
17 
18  namespace {
19  int numRow(int numVertex) {
20  return numVertex+5;
21  }
22  }
23 
24 
25  KalmanVertexOnJetAxisUpdator::KalmanVertexOnJetAxisUpdator(const std::string& t, const std::string& n, const IInterface* p):
26  AthAlgTool(t,n,p),
27  m_initialMomentumError(1000.)
28  {
29  declareInterface<KalmanVertexOnJetAxisUpdator>(this);
30  declareProperty("initialMomentumError",m_initialMomentumError);
31  }
32 
33 
35  {
37  if(sc.isFailure()){
38  ATH_MSG_ERROR (" Unable to initialize the AlgTool");
39  return StatusCode::FAILURE;
40  }
41  return StatusCode::SUCCESS;
42  }
43 
44 
46  const VxVertexOnJetAxis* vertexToUpdate,
47  VxJetCandidate* candidateToUpdate) const {
48  update(trackToAdd,vertexToUpdate,candidateToUpdate,1,false);
49  }
50 
51 
53  const VxVertexOnJetAxis* vertexToUpdate,
54  VxJetCandidate* candidateToUpdate) const {
55  update(trackToAdd,vertexToUpdate,candidateToUpdate,1,true);
56  }
57 
58 
60  const VxVertexOnJetAxis* vertexToUpdate,
61  VxJetCandidate* candidateToUpdate) const {
62  update(trackToRemove,vertexToUpdate,candidateToUpdate,-1,false);
63  }
64 
65 
67  const VxVertexOnJetAxis* vertexToUpdate,
68  VxJetCandidate* candidateToUpdate) const {
69  update(trackToRemove,vertexToUpdate,candidateToUpdate,-1,true);
70  }
71 
72 
74  const VxVertexOnJetAxis* vertexToUpdate,
75  VxJetCandidate* candidateToUpdate,
76  int sign,bool doFastUpdate) const {
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
136 
137 
138  //actual method where the position update happens
141  const LinearizedTrack * trk,
142  double trackWeight, int sign,
143  int numVertex, bool isPrimary,
144  bool doFastUpdate) const {
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
361 
363  const VxVertexOnJetAxis* vertexToUpdate,
364  VxJetCandidate* vertexCandidate) const {
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  }
427 
428 
430  const LinearizedTrack * trk,
431  double trackWeight,
432  int numVertex, bool isPrimary) const {
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  }
479 
480 
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  }
512 
513 
514  std::pair<Amg::Vector3D,Eigen::Matrix3Xd>
516  int numVertex,
517  bool isPrimary,
518  bool truncateDimensions) const {
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);
549  transform(0,Trk::jet_theta) = dist*cos(theta)*cos(phi);
550  transform(0,numrow_toupdate)= sin(theta)*cos(phi);
551  transform(1,Trk::jet_phi) = dist*sin(theta)*cos(phi);
552  transform(1,Trk::jet_theta) = dist*cos(theta)*sin(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  }
569 
570 
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  }
636 
637 }//end of namespace definition
Trk::VertexPositions::position
const Amg::VectorX & position() const
return position of vertex
Definition: VertexPositions.cxx:95
covarianceTool.ndf
ndf
Definition: covarianceTool.py:678
Trk::VxTrackAtVertex::trackQuality
FitQuality trackQuality(void) const
Returns a pointer to the original track if any.
Trk::AmgMatrix
AmgMatrix(3, 3) NeutralParticleParameterCalculator
Definition: NeutralParticleParameterCalculator.cxx:233
Amg::VectorX
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
Definition: EventPrimitives.h:32
Amg::MatrixX
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Definition: EventPrimitives.h:29
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
Trk::VxTrackAtVertex
The VxTrackAtVertex is a common class for all present TrkVertexFitters The VxTrackAtVertex is designe...
Definition: VxTrackAtVertex.h:77
Trk::KalmanVertexOnJetAxisUpdator::m_initialMomentumError
double m_initialMomentumError
Definition: KalmanVertexOnJetAxisUpdator.h:174
Trk::VxVertexOnJetAxis::getTracksAtVertex
const std::vector< VxTrackAtVertex * > & getTracksAtVertex(void) const
get Tracks At Vertex Method
Definition: VxVertexOnJetAxis.cxx:102
Trk::VxJetCandidate::getConstraintVertexPositions
const Trk::RecVertexPositions & getConstraintVertexPositions() const
Definition: VxJetCandidate.cxx:577
Trk::jet_theta
@ jet_theta
Definition: JetVtxParamDefs.h:28
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
Trk::VxJetCandidate::getLinearizationVertexPositions
const Trk::VertexPositions & getLinearizationVertexPositions() const
Definition: VxJetCandidate.cxx:531
initialize
void initialize()
Definition: run_EoverP.cxx:894
JetVtxParamDefs.h
VxVertexOnJetAxis.h
VxJetCandidate.h
Trk::VxVertexOnJetAxis
VxVertexOnJetAxis inherits from Vertex.
Definition: VxVertexOnJetAxis.h:79
Trk::jet_xv
@ jet_xv
Definition: JetVtxParamDefs.h:27
Trk::VxTrackAtVertex::weight
double weight(void) const
Information about the weight of track in fit (given back by annealing): weight=ndf/2.
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
Trk::KalmanVertexOnJetAxisUpdator::remove
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...
Definition: KalmanVertexOnJetAxisUpdator.cxx:59
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
Trk::KalmanVertexOnJetAxisUpdator::smartInvert
void smartInvert(Amg::MatrixX &new_vrt_cov) const
Definition: KalmanVertexOnJetAxisUpdator.cxx:571
JetTiledMap::S
@ S
Definition: TiledEtaPhiMap.h:44
Trk::KalmanVertexOnJetAxisUpdator::removeWithFastUpdate
void removeWithFastUpdate(VxTrackAtVertex *trackToRemove, const VxVertexOnJetAxis *vertexToUpdate, VxJetCandidate *candidateToUpdate) const
Definition: KalmanVertexOnJetAxisUpdator.cxx:66
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
Trk::VxJetCandidate::getRecVertexPositions
const Trk::RecVertexPositions & getRecVertexPositions() const
Definition: VxJetCandidate.cxx:519
Trk::AmgSymMatrix
AmgSymMatrix(5) &GXFTrackState
Definition: GXFTrackState.h:156
Trk::VxJetCandidate::getPrimaryVertex
const VxVertexOnJetAxis * getPrimaryVertex(void) const
Definition: VxJetCandidate.cxx:551
Trk::KalmanVertexOnJetAxisUpdator::addWithFastUpdate
void addWithFastUpdate(VxTrackAtVertex *trackToAdd, const VxVertexOnJetAxis *vertexToUpdate, VxJetCandidate *candidateToUpdate) const
Definition: KalmanVertexOnJetAxisUpdator.cxx:52
Trk::KalmanVertexOnJetAxisUpdator::KalmanVertexOnJetAxisUpdator
KalmanVertexOnJetAxisUpdator(const std::string &t, const std::string &n, const IInterface *p)
Constructor.
Definition: KalmanVertexOnJetAxisUpdator.cxx:25
Trk::KalmanVertexOnJetAxisUpdator::calculateTrackChi2
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.
Definition: KalmanVertexOnJetAxisUpdator.cxx:429
Trk::RecVertexPositions::setFitQuality
void setFitQuality(const Trk::FitQuality &)
Definition: RecVertexPositions.cxx:179
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Trk::KalmanVertexOnJetAxisUpdator::positionUpdate
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...
Definition: KalmanVertexOnJetAxisUpdator.cxx:140
lumiFormat.i
int i
Definition: lumiFormat.py:92
beamspotman.n
n
Definition: beamspotman.py:731
Trk::VxTrackAtVertex::setTrackQuality
void setTrackQuality(const FitQuality &trkQuality)
Set methods for various components.
Trk::theta
@ theta
Definition: ParamDefs.h:72
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
AmgVector
AmgVector(4) T2BSTrackFilterTool
Definition: T2BSTrackFilterTool.cxx:114
Trk::KalmanVertexOnJetAxisUpdator::initialize
virtual StatusCode initialize() override
Definition: KalmanVertexOnJetAxisUpdator.cxx:34
Trk::jet_yv
@ jet_yv
Definition: JetVtxParamDefs.h:27
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
chi2
double chi2(TH1 *h0, TH1 *h1)
Definition: comparitor.cxx:522
sign
int sign(int a)
Definition: TRT_StrawNeighbourSvc.h:127
VxTrackAtVertex.h
Trk::VxVertexOnJetAxis::getNumVertex
int getNumVertex(void) const
Get Method for NumVertex.
Definition: VxVertexOnJetAxis.cxx:98
Trk::KalmanVertexOnJetAxisUpdator::updateChi2NdfInfo
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...
Definition: KalmanVertexOnJetAxisUpdator.cxx:362
Trk::VxJetCandidate::setRecVertexPositions
void setRecVertexPositions(const Trk::RecVertexPositions &)
Definition: VxJetCandidate.cxx:527
Trk::RecVertexPositions::fitQuality
const Trk::FitQuality & fitQuality() const
Fit quality access method.
Definition: RecVertexPositions.cxx:167
Trk::VxTrackAtVertex::linState
LinearizedTrack * linState(void)
Access method for the perigee linearized track.
Trk
Ensure that the ATLAS eigen extensions are properly loaded.
Definition: FakeTrackBuilder.h:9
Trk::KalmanVertexOnJetAxisUpdator::add
void add(VxTrackAtVertex *trackToAdd, const VxVertexOnJetAxis *vertexToUpdate, VxJetCandidate *candidateToUpdate) const
Method updating the fit along the flight axis (VxJetCandidate) with a track (VxTrackOnJetAxis) which ...
Definition: KalmanVertexOnJetAxisUpdator.cxx:45
VP1PartSpect::E
@ E
Definition: VP1PartSpectFlags.h:21
Trk::jet_zv
@ jet_zv
position x,y,z of primary vertex
Definition: JetVtxParamDefs.h:27
Trk::VxJetCandidate
Definition: VxJetCandidate.h:72
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Trk::RecVertexPositions
Definition: RecVertexPositions.h:34
Trk::KalmanVertexOnJetAxisUpdator::update
void update(VxTrackAtVertex *trackToUpdate, const VxVertexOnJetAxis *vertexToUpdate, VxJetCandidate *candidateToUpdate, int sign, bool doFastUpdate) const
Internal method to do the Kalman Update.
Definition: KalmanVertexOnJetAxisUpdator.cxx:73
Trk::KalmanVertexOnJetAxisUpdator::createTransformJacobian
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...
Definition: KalmanVertexOnJetAxisUpdator.cxx:515
Trk::RecVertexPositions::covariancePosition
Amg::MatrixX const & covariancePosition() const
return the covDeltaV matrix of the vertex fit
Definition: RecVertexPositions.cxx:171
a
TList * a
Definition: liststreamerinfos.cxx:10
CondAlgsOpts.found
int found
Definition: CondAlgsOpts.py:101
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
F
#define F(x, y, z)
Definition: MD5.cxx:112
Trk::FitQuality::chiSquared
double chiSquared() const
returns the of the overall track fit
Definition: FitQuality.h:56
Trk::jet_phi
@ jet_phi
Definition: JetVtxParamDefs.h:28
Trk::phi
@ phi
Definition: ParamDefs.h:81
Trk::FitQuality::numberDoF
int numberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as integer
Definition: FitQuality.h:60
LinearizedTrack.h
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
Trk::VertexPositions
VertexPositions class to represent and store a vertex.
Definition: VertexPositions.h:36
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
AthAlgTool
Definition: AthAlgTool.h:26
RecVertexPositions.h
python.Dumpers.FitQuality
FitQuality
Definition: Dumpers.py:63
KalmanVertexOnJetAxisUpdator.h
Trk::KalmanVertexOnJetAxisUpdator::updateVertexChi2
void updateVertexChi2(VxJetCandidate *vertexCandidate) const
Obsolete (will be removed - not in use, however moved to eigen before finding out -WL).
Definition: KalmanVertexOnJetAxisUpdator.cxx:481
NSWL1::PadTriggerAdapter::segment
Muon::NSW_PadTriggerSegment segment(const NSWL1::PadTrigger &data)
Definition: PadTriggerAdapter.cxx:5
egammaParameters::isPrimary
@ isPrimary
true if matched track has a hit in first or second pixel layer
Definition: egammaParamDefs.h:225
Trk::LinearizedTrack
Definition: LinearizedTrack.h:43