ATLAS Offline Software
FullVertexFitter.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /***************************************************************************
6  FullVertexFitter.cxx - Description
7  ***************************************************************************/
14 #include "TrkTrack/LinkToTrack.h"
15 #include "TrkTrack/Track.h"
20 #include <cmath>
21 //xAOD includes
22 #include "xAODTracking/Vertex.h"
24 
25 /* These are some local helper classes only needed for convenience, therefor
26 within anonymous namespace. They do contain temporary calculations of matrices
27 and vectors resulting from the Billoir calculation (Note: no transformation
28 of the perigee parameters is done anymore).*/
29 namespace
30 {
31  struct BilloirTrack
32  {
33  BilloirTrack() : perigee ( nullptr ), originalPerigee( nullptr ), linTrack( nullptr ) {}
34  virtual ~BilloirTrack()
35  {
36  // linTrack needs to be deleted
37  delete linTrack; linTrack=nullptr;
38  }
39 
40  BilloirTrack(const BilloirTrack& arg)
41  {
42  linTrack = arg.linTrack->clone();
43  perigee = arg.perigee; // does not own it
44  originalPerigee = arg.originalPerigee; // does not own it
45  chi2 = arg.chi2 ;
46  Di_mat = arg.Di_mat ;
47  Ei_mat = arg.Ei_mat ;
48  Gi_mat = arg.Gi_mat ;
49  Bi_mat = arg.Bi_mat ;
50  Ci_inv = arg.Ci_inv ;
51  Ui_vec = arg.Ui_vec ;
52  BCi_mat = arg.BCi_mat;
53  Dper = arg.Dper ;
54  }
55 
56  Trk::TrackParameters * perigee;
57  const Trk::TrackParameters * originalPerigee;
58  Trk::LinearizedTrack * linTrack;
59  double chi2{};
60  AmgMatrix(5,3) Di_mat;
61  AmgMatrix(5,3) Ei_mat;
62  AmgMatrix(3,3) Gi_mat;
63  AmgMatrix(3,3) Bi_mat; // Bi = Di.T * Wi * Ei
64  AmgMatrix(3,3) Ci_inv; // Ci = (Ei.T * Wi * Ei)^-1
65  Amg::Vector3D Ui_vec; // Ui = Ei.T * Wi * dqi
66  AmgMatrix(3,3) BCi_mat; // BCi = Bi * Ci^-1
67  AmgVector(5) Dper;
68  };
69 
70  struct BilloirVertex
71  {
72  BilloirVertex()
73  {
74  A_mat.setZero();
75  T_vec.setZero();
76  BCB_mat.setZero();
77  BCU_vec.setZero();
78  };
79  double chi2{};
80  unsigned int ndf{};
81  AmgMatrix(3,3) A_mat; // T = sum{Di.T * Wi * Di}
82  Amg::Vector3D T_vec; // A = sum{Di.T * Wi * dqi}
83  AmgMatrix(3,3) BCB_mat; // BCB = sum{Bi * Ci^-1 * Bi.T}
84  Amg::Vector3D BCU_vec; // BCU = sum{Bi * Ci^-1 * Ui}
85  };
86 }
87 
88 namespace Trk
89 {
91  {
92 
93 
94  if ( m_linFactory.retrieve().isFailure() )
95  {
96  msg(MSG::FATAL)<< "Failed to retrieve tool " << m_linFactory << endmsg;
97  return StatusCode::FAILURE;
98  }
99 
100 
101  msg(MSG::INFO) << "Retrieved tool " << m_linFactory << endmsg;
102 
103 
104  return StatusCode::SUCCESS;
105  }
106 
107  FullVertexFitter::FullVertexFitter ( const std::string& t, const std::string& n, const IInterface* p ) : base_class ( t,n,p ),
108  m_maxIterations ( 5 ),
109  m_maxDchi2PerNdf ( 0.000001 )
110 
111  {
112  declareProperty ( "MaxIterations", m_maxIterations );
113  declareProperty ( "MaxChi2PerNdf", m_maxDchi2PerNdf );
114  declareProperty ( "LinearizedTrackFactory", m_linFactory );
115  declareInterface<IVertexFitter> ( this );
116  }
117 
119 
121  xAOD::Vertex * FullVertexFitter::fit ( const std::vector<const Trk::TrackParameters*> & originalPerigees,
122  const Amg::Vector3D& firstStartingPoint ) const
123  {
124  xAOD::Vertex constraint;
125  constraint.makePrivateStore();
126  constraint.setPosition( firstStartingPoint );
127  constraint.setCovariancePosition( AmgSymMatrix(3)(3,3) );
128  constraint.setFitQuality( 0.,0.);
129  return fit ( originalPerigees, constraint );
130  }
131 
134  xAOD::Vertex * FullVertexFitter::fit ( const std::vector<const Trk::TrackParameters*> & originalPerigees,
135  const xAOD::Vertex& firstStartingPoint ) const
136  {
137  if ( originalPerigees.empty() )
138  {
139  ATH_MSG_VERBOSE("No tracks to fit in this event.");
140  return nullptr;
141  }
142 
143  /* Initialisation of variables */
144  double chi2 = 2000000000000.;
145  unsigned int nRP = originalPerigees.size(); // Number of tracks to fit
146  int ndf = nRP * ( 5-3 ) - 3; // Number of degrees of freedom
147  if ( ndf < 0 ) {ndf = 1;}
148 
149  /* Determine if we are doing a constraint fit.*/
150  bool constraint = false;
151  if ( firstStartingPoint.covariancePosition().trace() != 0. )
152  {
153  constraint = true;
154  ndf += 3;
155  ATH_MSG_DEBUG("Fitting with constraint.");
156  ATH_MSG_VERBOSE(firstStartingPoint.covariancePosition().inverse());
157  }
158 
159  double chi2New=0.;
160 
161  Amg::Vector3D linPoint ( firstStartingPoint.position() ); // linearization point for track parameters (updated for every iteration)
162 
164 
165  std::vector<Amg::Vector3D> mom_at_Origin;
166 
167  xAOD::Vertex * fittedVertex = new xAOD::Vertex;
168  fittedVertex->makePrivateStore(); // xAOD::VertexContainer will take ownership of AuxStore when ActualVertex is added to it
169 
170  std::vector<VxTrackAtVertex> tracksAtVertex;
171  std::vector<BilloirTrack> billoirTracks;
172 
173  /* Iterate fits until the fit criteria are met, or the number of max
174  iterations is reached. */
175  for ( unsigned int niter=0; niter < m_maxIterations; ++niter )
176  {
177  ATH_MSG_VERBOSE("Start of iteration " << niter << ", starting point ("
178  << linPoint [0] << ", " << linPoint [1] << ", " << linPoint [2]
179  << ") and " << originalPerigees.size() << " tracks.");
180 
181  billoirTracks.clear();
182  chi2New = 0.;
183 
184  AmgMatrix(2,3) D;
185  BilloirVertex billoirVertex;
186 
187  /* Linearize the track parameters wrt. starting point of the fit */
188  Amg::Vector3D globalPosition = linPoint;
189  Trk::PerigeeSurface perigeeSurface ( globalPosition );
190 
191  /* Extrapolate the perigees to the startpoint of the fit */
192  unsigned int count(0);
193  for (const auto *originalPerigee : originalPerigees)
194  {
195 
196  if ( niter == 0 )
197  {
198  // need to cast to access parameters() (this is to guarantee that the code knows if it is neutrals or charged parameters)
199  const Trk::TrackParameters* chargedParameters ( nullptr );
200  chargedParameters = dynamic_cast<const Trk::TrackParameters*> ( originalPerigee );
201  if ( chargedParameters==nullptr )
202  {
203  ATH_MSG_ERROR("Track parameters are not charged tracks ... full fit aborted (this will be handled correctly soon)");
204  return nullptr;
205  }
206 
207 
208  p0.x() = chargedParameters->parameters() [Trk::phi];
209  p0.y() = chargedParameters->parameters() [Trk::theta];
210  p0.z() = chargedParameters->parameters() [Trk::qOverP] ;
211  mom_at_Origin.push_back ( p0 );
212 
213  }
214 
215  // FOR NOW THE ONLY WAY TO CHECK IF EXTRAPOLATION WORKED IS TO CHECK THE RETURN POINTER
216  // if it is ZERO then take the original perigee
217  // there is a tiny tiny chance that the extrapolation fails because of a non converging runge kutta procedure
218  // in all other cases it did not extrapolate because the reference surface of the original perigee
219  // is already given to the extrapolation point (or very close nearby)
220 
221  LinearizedTrack* linTrack = m_linFactory->linearizedTrack ( originalPerigee, linPoint );
222  if ( linTrack==nullptr )
223  {
224  ATH_MSG_DEBUG("Could not linearize track! Skipping this track!");
225  }
226  else
227  {
228  BilloirTrack locBilloirTrack;
229 
230  locBilloirTrack.originalPerigee = originalPerigee;
231  locBilloirTrack.linTrack = linTrack;
232  double d0 = linTrack->expectedParametersAtPCA()[Trk::d0];
233  double z0 = linTrack->expectedParametersAtPCA()[Trk::z0];
234  double phi = linTrack->expectedParametersAtPCA()[Trk::phi];
235  double theta = linTrack->expectedParametersAtPCA()[Trk::theta];
236  double qOverP = linTrack->expectedParametersAtPCA()[Trk::qOverP];
237 
238  // calculate f(V_0,p_0) f_d0 = f_z0 = 0
239  double f_phi = mom_at_Origin[count] ( 0 );
240  double f_theta = mom_at_Origin[count] ( 1 );
241  double f_qOverP = mom_at_Origin[count] ( 2 );
242 
243  //calculate Dper[i]
244  locBilloirTrack.Dper[0] = d0;
245  locBilloirTrack.Dper[1] = z0;
246  locBilloirTrack.Dper[2] = phi - f_phi;
247  locBilloirTrack.Dper[3] = theta - f_theta;
248  locBilloirTrack.Dper[4] = qOverP -f_qOverP;
249 
250  // the D matrix
251  AmgMatrix(5,3) D_mat;
252  D_mat.setZero();
253  D_mat = linTrack->positionJacobian();
254 
255  // calculate the E matrix
256  AmgMatrix(5,3) E_mat;
257  E_mat.setZero();
258  E_mat = linTrack->momentumJacobian();
259 
260  // and cache martix operations related to these matrices
261  AmgMatrix(3,5) Dt_W_mat;
262  Dt_W_mat.setZero();
263  AmgMatrix(3,5) Et_W_mat;
264  Et_W_mat.setZero();
265  Dt_W_mat = D_mat.transpose() * ( linTrack->expectedWeightAtPCA() );
266  Et_W_mat = E_mat.transpose() * ( linTrack->expectedWeightAtPCA() );
267 
268  // these are the Billoir computed results
269  locBilloirTrack.Di_mat = D_mat;
270  locBilloirTrack.Ei_mat = E_mat;
271  locBilloirTrack.Gi_mat = Et_W_mat*E_mat;
272  locBilloirTrack.Bi_mat = Dt_W_mat * E_mat; // Di.T * Wi * Ei
273  locBilloirTrack.Ui_vec = Et_W_mat * locBilloirTrack.Dper; // Ei.T * Wi * dqi
274  locBilloirTrack.Ci_inv = Et_W_mat * E_mat ; // (Ei.T * Wi * Ei)^-1
275  // we need the inverse matrix here
276  locBilloirTrack.Ci_inv = locBilloirTrack.Ci_inv.inverse().eval();
277  // sum up over all tracks
278  billoirVertex.T_vec += Dt_W_mat * locBilloirTrack.Dper; // sum{Di.T * Wi * dqi}
279  billoirVertex.A_mat = billoirVertex.A_mat + Dt_W_mat * D_mat ; // sum{Di.T * Wi * Di}
280 
281  // remember those results for all tracks
282  locBilloirTrack.BCi_mat = locBilloirTrack.Bi_mat * locBilloirTrack.Ci_inv; // BCi = Bi * Ci^-1
283 
284  // and some summed results
285  billoirVertex.BCU_vec += locBilloirTrack.BCi_mat * locBilloirTrack.Ui_vec; // sum{Bi * Ci^-1 * Ui}
286  billoirVertex.BCB_mat = billoirVertex.BCB_mat + locBilloirTrack.BCi_mat * locBilloirTrack.Bi_mat.transpose() ;// sum{Bi * Ci^-1 * Bi.T}
287  billoirTracks.push_back ( locBilloirTrack );
288  count++;
289 
290  }
291  }
292 
293  // calculate delta (billoirFrameOrigin-position), might be changed by the beam-const
294  Amg::Vector3D V_del = billoirVertex.T_vec - billoirVertex.BCU_vec; // V_del = T-sum{Bi*Ci^-1*Ui}
295  AmgMatrix(3,3) V_wgt_mat = billoirVertex.A_mat - billoirVertex.BCB_mat; // V_wgt = A-sum{Bi*Ci^-1*Bi.T}
296 
297  if ( constraint )
298  {
299  // add V_del += wgtconst * (billoirFrameOrigin - Vconst) and V_wgt +=wgtconst
300  Amg::Vector3D constraintPosInBilloirFrame;
301  constraintPosInBilloirFrame.setZero();
302  // this will be 0 for first iteration but != 0 from second on
303  constraintPosInBilloirFrame[0] = firstStartingPoint.position() [0]-linPoint [0];
304  constraintPosInBilloirFrame[1] = firstStartingPoint.position() [1]-linPoint [1];
305  constraintPosInBilloirFrame[2] = firstStartingPoint.position() [2]-linPoint [2];
306 
307  V_del += firstStartingPoint.covariancePosition().inverse() *constraintPosInBilloirFrame;
308  V_wgt_mat += firstStartingPoint.covariancePosition().inverse();
309  }
310  // cov(delta_V) = V_wgt^-1
311  AmgMatrix(3,3) cov_delta_V_mat = V_wgt_mat.inverse().eval() ;
312 
313  // delta_V = cov_(delta_V) * V_del;
314  Amg::Vector3D delta_V = cov_delta_V_mat * V_del;
315  /* Momentum Calculation follows here. */
316  /* ---------------------------------------------------------------------------------------- */
317  std::vector<AmgMatrix(5,5)> cov_delta_P_mat ( nRP );
318  std::vector<double> chi2PerTrack;
319  chi2PerTrack.clear();
320 
321  // ===> loop over tracks
323  int iRP =0;
324  for ( BTIter = billoirTracks.begin(); BTIter != billoirTracks.end() ; ++BTIter )
325  {
326  // delta_P calculation
327  BilloirTrack locP ( ( *BTIter ) );
328  Amg::Vector3D delta_P = ( locP.Ci_inv ) * ( ( locP.Ui_vec )- ( locP.Bi_mat.transpose() ) *delta_V );
329  mom_at_Origin[iRP] ( 0 ) += delta_P[0];
330  if ( fabs ( mom_at_Origin[iRP] ( 0 ) ) > 10*M_PI )
331  { // protect while loop
332  if (msgLvl(MSG::WARNING))
333  {
334  msg(MSG::WARNING) << " Track direction angles have numerical problems, stop perigee parameter update." << endmsg;
335  msg(MSG::WARNING) << " Phi value: "<<mom_at_Origin[iRP] ( 0 ) <<endmsg;
336  }
337  return nullptr;
338  }
339  mom_at_Origin[iRP] ( 1 ) += delta_P[1];
340  if ( fabs ( mom_at_Origin[iRP] ( 0 ) ) > 5*M_PI )
341  { // protect while loop
342  if (msgLvl(MSG::WARNING))
343  {
344  msg(MSG::WARNING) << " Track direction angles have numerical problems, stop perigee parameter update." << endmsg;
345  msg(MSG::WARNING) << " Theta value: "<<mom_at_Origin[iRP] ( 1 ) <<endmsg;
346  }
347  return nullptr;
348  }
349  mom_at_Origin[iRP] ( 2 ) += delta_P[2];
350  // mom_at_Origin[iRP](0) -= M_PI > M_PI ? M_PI : 0;
351  // mom_at_Origin[iRP](0) += M_PI < -M_PI ? M_PI : 0;
352  //correct phi, theta coordinates
353  while ( fabs ( mom_at_Origin[iRP] ( 0 ) ) > M_PI ) mom_at_Origin[iRP] ( 0 ) += ( mom_at_Origin[iRP] ( 0 ) > 0 ) ? -2*M_PI : 2*M_PI;
354  while ( mom_at_Origin[iRP] ( 1 ) > 2*M_PI ) mom_at_Origin[iRP] ( 1 ) -= 2*M_PI;
355  while ( mom_at_Origin[iRP] ( 1 ) < -M_PI ) mom_at_Origin[iRP] ( 1 ) += M_PI;
356  if ( mom_at_Origin[iRP] ( 1 ) > M_PI )
357  {
358  mom_at_Origin[iRP] ( 1 ) = 2*M_PI - mom_at_Origin[iRP] ( 1 );
359  if ( mom_at_Origin[iRP] ( 0 ) >= 0 ) mom_at_Origin[iRP] ( 0 ) += ( mom_at_Origin[iRP] ( 0 ) >0 ) ? -M_PI : M_PI;
360  }
361  if ( mom_at_Origin[iRP] ( 1 ) < 0.0 )
362  {
363  mom_at_Origin[iRP] ( 1 ) = - mom_at_Origin[iRP] ( 1 );
364  if ( mom_at_Origin[iRP] ( 0 ) >= 0 ) mom_at_Origin[iRP] ( 0 ) += ( mom_at_Origin[iRP] ( 0 ) >0 ) ? -M_PI : M_PI;
365  }
366 
367  //calculate 5x5 cov_delta_P matrix
368  // d(d0,z0,phi,theta,qOverP)/d(x,y,z,phi,theta,qOverP)-transformation matrix
369  AmgMatrix(5,6) trans_mat;
370  trans_mat.setZero();
371  trans_mat ( 0,0 ) = locP.Di_mat ( 0,0 ); trans_mat ( 0,1 ) = locP.Di_mat ( 0,1 );
372  trans_mat ( 1,0 ) = locP.Di_mat ( 1,0 ); trans_mat ( 1,1 ) = locP.Di_mat ( 1,1 ); trans_mat ( 1,2 ) = 1.;
373  trans_mat ( 2,3 ) = 1.; trans_mat ( 3,4 ) = 1.; trans_mat ( 4,5 ) = 1.;
374 
375  //some intermediate calculations to get 5x5 matrix
376  //cov(V,V)
377  AmgMatrix(3,3) V_V_mat; V_V_mat.setZero(); V_V_mat = cov_delta_V_mat ;
378  // std::cout<<"V_V_mat = "<<V_V_mat<<std::endl;
379  //cov(V,P)
380  AmgMatrix(3,3) V_P_mat; V_P_mat.setZero(); V_P_mat = -cov_delta_V_mat*locP.Gi_mat*locP.Ci_inv ;
381  // std::cout<<"V_P_mat = "<<V_P_mat<<std::endl;
382  //cov(P,P)
383  AmgMatrix(3,3) P_P_mat; P_P_mat.setZero(); P_P_mat = locP.Ci_inv + locP.BCi_mat.transpose() *cov_delta_V_mat*locP.BCi_mat ;
384  // std::cout<<"P_P_mat = "<<P_P_mat<<std::endl;
385 
386  AmgMatrix(6,6) cov_mat;
387  cov_mat.setZero();
388  cov_mat.block<3,3>(0,3) = V_P_mat;
389  cov_mat.block<3,3>(3,0) = V_P_mat.transpose() ;
390  cov_mat.block<3,3>(0,0) = V_V_mat ;
391  cov_mat.block<3,3>(3,3) = P_P_mat ;
392 
393  // cov_delta_P calculation
394  // std::cout<<"trans_mat = "<<trans_mat<<std::endl;
395  cov_delta_P_mat[iRP] = trans_mat*cov_mat*trans_mat.transpose() ;
396  // std::cout<<"cov_delta_P_mat[iRP] = "<<cov_delta_P_mat[iRP]<<std::endl;
397 
398  ++iRP;
399 
400  /* Calculate chi2 per track. */
401  ( *BTIter ).chi2= ( ( ( *BTIter ).Dper- ( *BTIter ).Di_mat*delta_V - ( *BTIter ).Ei_mat*delta_P ).transpose() * ( *BTIter ).linTrack->expectedWeightAtPCA() * ( ( *BTIter ).Dper - ( *BTIter ).Di_mat*delta_V - ( *BTIter ).Ei_mat*delta_P ) ) [0];
402 
403  if ( ( *BTIter ).chi2 < 0 )
404  {
405  ATH_MSG_WARNING( "FullVertexFitter::calculate: error in chi2_per_track" );
406  return nullptr;
407  }
408  chi2New += ( *BTIter ).chi2;
409  }
410 
411  if ( constraint )
412  {
413  Amg::Vector3D deltaTrk;
414  deltaTrk.setZero();
415  // last term will also be 0 again but only in the first iteration
416  // = calc. vtx in billoir frame - ( constraint pos. in billoir frame )
417  deltaTrk[0] = delta_V[0] - ( firstStartingPoint.position() [0] - linPoint [0] );
418  deltaTrk[1] = delta_V[1] - ( firstStartingPoint.position() [1] - linPoint [1] );
419  deltaTrk[2] = delta_V[2] - ( firstStartingPoint.position() [2] - linPoint [2] );
420  chi2New += ( deltaTrk.transpose() * firstStartingPoint.covariancePosition().inverse() * deltaTrk ) [0];
421  }
422 
423  /* assign new linearization point (= new vertex position in global frame) */
424  Amg::Vector3D tmpPos ( linPoint );
425  tmpPos[0] += delta_V[0]; tmpPos[1] += delta_V[1]; tmpPos[2] += delta_V[2];
426  linPoint = tmpPos;
427 
428  if ( chi2New < chi2 )
429  {
430  /* Store the vertex */
431  chi2 = chi2New;
432  //const AmgMatrix(3,3) * newCovarianceMatrix = &cov_delta_V_mat ;
433  //const AmgMatrix(3,3) newErrorMatrix = newCovarianceMatrix->inverse().eval();
434  //fittedVertex = RecVertex ( linPoint.position(), newErrorMatrix, ndf, chi2 );
435 
436  //the cov_delta_V_mat is already the inverted form. -katy 2/2/16
437  fittedVertex->setPosition( linPoint );
438  fittedVertex->setCovariancePosition( cov_delta_V_mat );
439  fittedVertex->setFitQuality( chi2, ndf );
440 
441  // new go through vector and delete entries
442  /* // TODO: not needed anymore, tracksAtVertex doesn't store pointers - just the objects themselves <David Shope> (EDM Migration) 03/21/16
443  for ( std::vector<Trk::VxTrackAtVertex*>::const_iterator itr = tracksAtVertex.begin();
444  itr != tracksAtVertex.end(); ++itr )
445  {
446  delete ( *itr );
447  }
448  */
449 
450  tracksAtVertex.clear();
451  /* Store the tracks at vertex */
452  Amg::Vector3D Vertex(linPoint[0], linPoint[1], linPoint[2]);
454  TrackParameters * refittedPerigee ( nullptr );
455  unsigned int iter= 0;
457  for ( BTIter = billoirTracks.begin(); BTIter != billoirTracks.end() ; ++BTIter )
458  {
459  const AmgMatrix(5,5) * newTrackCovarianceMatrix = &cov_delta_P_mat[iter] ;
460  //Covariance matrix does not need to be inverted:
461  // AmgMatrix(5,5) newTrackErrorMatrix = (AmgMatrix(5,5)) newTrackCovarianceMatrix->inverse().eval();
462  AmgMatrix(5,5) newTrackErrorMatrix = (AmgMatrix(5,5)) newTrackCovarianceMatrix->eval();
463  refittedPerigee = new Trk::Perigee ( 0.,0.,mom_at_Origin[iter][0],mom_at_Origin[iter][1],mom_at_Origin[iter][2],
464  Surface, std::move(newTrackErrorMatrix) );
465  Trk::VxTrackAtVertex* tmpVxTrkAtVtx = new Trk::VxTrackAtVertex ( ( *BTIter ).chi2, refittedPerigee, ( *BTIter ).originalPerigee );
466  tracksAtVertex.push_back ( *tmpVxTrkAtVtx );
467  iter ++;
468  }
469  }
470  } // end of iteration
471  fittedVertex->vxTrackAtVertex() = tracksAtVertex;
472  //ATH_MSG_VERBOSE("Final Vertex Fitted: " << fittedVxCandidate->recVertex()); // TODO: can no longer print vertex after converting to xAOD
473  return fittedVertex;
474  }
475 
476  xAOD::Vertex * FullVertexFitter::fit ( const std::vector<const Trk::TrackParameters*>& perigeeList ) const
477  {
478  Amg::Vector3D tmpVtx(0.,0.,0.);
479  return fit ( perigeeList, tmpVtx );
480  }
481 
482 
483  //xAOD interfaced methods. Required to un-block the current situation
484  // with the xAOD tracking design.
485  xAOD::Vertex * FullVertexFitter::fit(const std::vector<const xAOD::TrackParticle*>& vectorTrk,const Amg::Vector3D& startingPoint) const
486  {
487  xAOD::Vertex constraint;
488  constraint.makePrivateStore();
489  constraint.setPosition( startingPoint );
490  constraint.setCovariancePosition( AmgSymMatrix(3)(3,3) );
491  constraint.setFitQuality( 0.,0.);
492  return fit(vectorTrk, constraint);
493  }//end of the xAOD starting point fit method
494 
495 
496  xAOD::Vertex * FullVertexFitter::fit(const std::vector<const xAOD::TrackParticle*>& vectorTrk, const xAOD::Vertex& constraint) const
497  {
498  if(vectorTrk.empty())
499  {
500  msg(MSG::INFO)<<"Empty vector of tracks passed"<<endmsg;
501  return nullptr;
502  }
503 
504  //making a list of perigee out of the vector of tracks
505  std::vector<const Trk::TrackParameters*> measuredPerigees;
506 
507  for(const auto *i : vectorTrk)
508  {
509  const Trk::TrackParameters * tmpMeasPer = &(i->perigeeParameters());
510 
511  if(tmpMeasPer!=nullptr) measuredPerigees.push_back(tmpMeasPer);
512  else msg(MSG::INFO)<<"Failed to dynamic_cast this track parameters to perigee"<<endmsg; //TODO: Failed to implicit cast the perigee parameters to track parameters?
513  }
514 
515 
516  xAOD::Vertex* fittedVertex = fit( measuredPerigees, constraint );
517 
518  //assigning the input tracks to the fitted vertex through VxTrackAtVertices
519  {
520  if( fittedVertex->vxTrackAtVertexAvailable() ) // TODO: I don't think vxTrackAtVertexAvailable() does the same thing as a null pointer check!
521  {
522  if(!fittedVertex->vxTrackAtVertex().empty())
523  {
524  for(unsigned int i = 0; i <vectorTrk.size(); ++i)
525  {
526 
528  linkTT->setElement(vectorTrk[i]);
529 
530  // vxtrackatvertex takes ownership!
531  ( fittedVertex->vxTrackAtVertex() )[i].setOrigTrack(linkTT);
532  }//end of loop for setting orig tracks in.
533  }//end of protection against unsuccessfull updates (no tracks were added)
534  }//end of vector of tracks check
535  }//end of pointer check
536 
537  //now set links to xAOD::TrackParticles directly in the xAOD::Vertex
538  unsigned int VTAVsize = fittedVertex->vxTrackAtVertex().size();
539  for (unsigned int i = 0 ; i < VTAVsize ; ++i)
540  {
541  Trk::VxTrackAtVertex* VTAV = &( fittedVertex->vxTrackAtVertex().at(i) );
542  //TODO: Will this pointer really hold 0 if no VxTrackAtVertex is found?
543  if (not VTAV){
544  ATH_MSG_WARNING (" Trying to set link to xAOD::TrackParticle. The VxTrackAtVertex is not found");
545  continue;
546  }
547 
548  Trk::ITrackLink* trklink = VTAV->trackOrParticleLink();
549 
550  // See if the trklink is to an xAOD::TrackParticle
551  Trk::LinkToXAODTrackParticle* linkToXAODTP = dynamic_cast<Trk::LinkToXAODTrackParticle*>(trklink);
552  if (linkToXAODTP)
553  {
554 
555  //Now set the new link to the xAOD vertex
556  fittedVertex->addTrackAtVertex(*linkToXAODTP, VTAV->weight());
557 
558  } else {
559  ATH_MSG_WARNING ("Skipping track. Trying to set link to something else than xAOD::TrackParticle. Neutrals not supported.");
560  }
561  } //end of loop
562 
563  return fittedVertex;
564 
565  }//end of the xAOD constrained fit method
566 
567 
568 
569 }
570 
571 
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
covarianceTool.ndf
ndf
Definition: covarianceTool.py:678
LinkToTrack.h
Trk::FullVertexFitter::~FullVertexFitter
virtual ~FullVertexFitter()
standard destructor
Trk::Vertex
Definition: Tracking/TrkEvent/VxVertex/VxVertex/Vertex.h:26
Trk::AmgMatrix
AmgMatrix(3, 3) NeutralParticleParameterCalculator
Definition: NeutralParticleParameterCalculator.cxx:233
xAOD::Vertex_v1::setPosition
void setPosition(const Amg::Vector3D &position)
Sets the 3-position.
xAOD::Vertex_v1::setFitQuality
void setFitQuality(float chiSquared, float numberDoF)
Set the 'Fit Quality' information.
Definition: Vertex_v1.cxx:150
Trk::VxTrackAtVertex
The VxTrackAtVertex is a common class for all present TrkVertexFitters The VxTrackAtVertex is designe...
Definition: VxTrackAtVertex.h:77
Trk::FullVertexFitter::m_maxDchi2PerNdf
double m_maxDchi2PerNdf
Definition: FullVertexFitter.h:165
xAOD::Vertex
Vertex_v1 Vertex
Define the latest version of the vertex class.
Definition: Event/xAOD/xAODTracking/xAODTracking/Vertex.h:16
python.Constants.FATAL
int FATAL
Definition: Control/AthenaCommon/python/Constants.py:19
PerigeeSurface.h
FullVertexFitter.h
Trk::PerigeeSurface
Definition: PerigeeSurface.h:43
initialize
void initialize()
Definition: run_EoverP.cxx:894
TrackParticleBase.h
M_PI
#define M_PI
Definition: ActiveFraction.h:11
Trk::z0
@ z0
Definition: ParamDefs.h:64
xAOD::Vertex_v1::position
const Amg::Vector3D & position() const
Returns the 3-pos.
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
Trk::Perigee
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
Definition: Tracking/TrkEvent/TrkParameters/TrkParameters/TrackParameters.h:33
AmgMatrix
#define AmgMatrix(rows, cols)
Definition: EventPrimitives.h:49
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
Track.h
Trk::AmgSymMatrix
AmgSymMatrix(5) &GXFTrackState
Definition: GXFTrackState.h:156
GeometryStatics.h
xAOD::Vertex_v1::addTrackAtVertex
void addTrackAtVertex(const ElementLink< TrackParticleContainer > &tr, float weight=1.0)
Add a new track to the vertex.
Definition: Vertex_v1.cxx:314
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
LinkToXAODTrackParticle.h
lumiFormat.i
int i
Definition: lumiFormat.py:85
Trk::FullVertexFitter::m_maxIterations
unsigned int m_maxIterations
Definition: FullVertexFitter.h:161
beamspotman.n
n
Definition: beamspotman.py:731
Trk::theta
@ theta
Definition: ParamDefs.h:66
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
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
TrackCollection.h
chi2
double chi2(TH1 *h0, TH1 *h1)
Definition: comparitor.cxx:523
VxTrackAtVertex.h
Trk::LinkToXAODTrackParticle
Element link to XAOD TrackParticle.
Definition: LinkToXAODTrackParticle.h:33
Trk::ParametersBase
Definition: ParametersBase.h:55
Vertex.h
LinkToTrackParticleBase.h
create_dcsc_inputs_sqlite.arg
list arg
Definition: create_dcsc_inputs_sqlite.py:48
Trk
Ensure that the ATLAS eigen extensions are properly loaded.
Definition: FakeTrackBuilder.h:9
Amg
Definition of ATLAS Math & Geometry primitives (Amg)
Definition: AmgStringHelpers.h:19
Trk::d0
@ d0
Definition: ParamDefs.h:63
SG::AuxElement::makePrivateStore
void makePrivateStore()
Create a new (empty) private store for this object.
Definition: AuxElement.cxx:192
Trk::FullVertexFitter::m_linFactory
ToolHandle< Trk::IVertexLinearizedTrackFactory > m_linFactory
Data members to store the results.
Definition: FullVertexFitter.h:169
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
TrackParticle.h
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
IVertexLinearizedTrackFactory.h
Trk::qOverP
@ qOverP
perigee
Definition: ParamDefs.h:67
Trk::phi
@ phi
Definition: ParamDefs.h:75
LinearizedTrack.h
Trk::FullVertexFitter::fit
virtual xAOD::Vertex * fit(const std::vector< const Trk::TrackParameters * > &perigeeList, const Amg::Vector3D &startingPoint) const override
Interface for ParametersBase with starting point.
Definition: FullVertexFitter.cxx:121
xAOD::Vertex_v1::vxTrackAtVertex
std::vector< Trk::VxTrackAtVertex > & vxTrackAtVertex()
Non-const access to the VxTrackAtVertex vector.
Definition: Vertex_v1.cxx:181
Trk::Surface
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:75
xAOD::Vertex_v1::vxTrackAtVertexAvailable
bool vxTrackAtVertexAvailable() const
Check if VxTrackAtVertices are attached to the object.
Definition: Vertex_v1.cxx:209
xAOD::Vertex_v1::setCovariancePosition
void setCovariancePosition(const AmgSymMatrix(3)&covariancePosition)
Sets the vertex covariance matrix.
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
TRTCalib_cfilter.p0
p0
Definition: TRTCalib_cfilter.py:129
Trk::LinearizedTrack
Definition: LinearizedTrack.h:43