ATLAS Offline Software
Loading...
Searching...
No Matches
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 ***************************************************************************/
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
26within anonymous namespace. They do contain temporary calculations of matrices
27and vectors resulting from the Billoir calculation (Note: no transformation
28of the perigee parameters is done anymore).*/
29namespace
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
88namespace 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
163 Amg::Vector3D p0;
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
322 std::vector<BilloirTrack>::iterator BTIter;
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;
456 std::vector<BilloirTrack>::iterator BTIter;
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
#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