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