33 BilloirTrack() : perigee ( nullptr ), originalPerigee( nullptr ), linTrack( nullptr ) {}
34 virtual ~BilloirTrack()
37 delete linTrack; linTrack=
nullptr;
40 BilloirTrack(
const BilloirTrack&
arg)
42 linTrack =
arg.linTrack->clone();
43 perigee =
arg.perigee;
44 originalPerigee =
arg.originalPerigee;
52 BCi_mat =
arg.BCi_mat;
94 if ( m_linFactory.retrieve().isFailure() )
97 return StatusCode::FAILURE;
101 msg(MSG::INFO) <<
"Retrieved tool " << m_linFactory <<
endmsg;
104 return StatusCode::SUCCESS;
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 )
114 declareProperty (
"LinearizedTrackFactory",
m_linFactory );
115 declareInterface<IVertexFitter> (
this );
129 return fit ( originalPerigees, constraint );
137 if ( originalPerigees.empty() )
144 double chi2 = 2000000000000.;
145 unsigned int nRP = originalPerigees.size();
146 int ndf = nRP * ( 5-3 ) - 3;
150 bool constraint =
false;
151 if ( firstStartingPoint.covariancePosition().trace() != 0. )
165 std::vector<Amg::Vector3D> mom_at_Origin;
170 std::vector<VxTrackAtVertex> tracksAtVertex;
171 std::vector<BilloirTrack> billoirTracks;
178 << linPoint [0] <<
", " << linPoint [1] <<
", " << linPoint [2]
179 <<
") and " << originalPerigees.size() <<
" tracks.");
181 billoirTracks.clear();
185 BilloirVertex billoirVertex;
192 unsigned int count(0);
193 for (
const auto *originalPerigee : originalPerigees)
201 if ( chargedParameters==
nullptr )
203 ATH_MSG_ERROR(
"Track parameters are not charged tracks ... full fit aborted (this will be handled correctly soon)");
208 p0.x() = chargedParameters->parameters() [
Trk::phi];
211 mom_at_Origin.push_back (
p0 );
222 if ( linTrack==
nullptr )
224 ATH_MSG_DEBUG(
"Could not linearize track! Skipping this track!");
228 BilloirTrack locBilloirTrack;
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];
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 );
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;
253 D_mat = linTrack->positionJacobian();
258 E_mat = linTrack->momentumJacobian();
265 Dt_W_mat = D_mat.transpose() * ( linTrack->expectedWeightAtPCA() );
266 Et_W_mat = E_mat.transpose() * ( linTrack->expectedWeightAtPCA() );
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;
273 locBilloirTrack.Ui_vec = Et_W_mat * locBilloirTrack.Dper;
274 locBilloirTrack.Ci_inv = Et_W_mat * E_mat ;
276 locBilloirTrack.Ci_inv = locBilloirTrack.Ci_inv.inverse().eval();
278 billoirVertex.T_vec += Dt_W_mat * locBilloirTrack.Dper;
279 billoirVertex.A_mat = billoirVertex.A_mat + Dt_W_mat * D_mat ;
282 locBilloirTrack.BCi_mat = locBilloirTrack.Bi_mat * locBilloirTrack.Ci_inv;
285 billoirVertex.BCU_vec += locBilloirTrack.BCi_mat * locBilloirTrack.Ui_vec;
286 billoirVertex.BCB_mat = billoirVertex.BCB_mat + locBilloirTrack.BCi_mat * locBilloirTrack.Bi_mat.transpose() ;
287 billoirTracks.push_back ( locBilloirTrack );
294 Amg::Vector3D V_del = billoirVertex.T_vec - billoirVertex.BCU_vec;
295 AmgMatrix(3,3) V_wgt_mat = billoirVertex.A_mat - billoirVertex.BCB_mat;
301 constraintPosInBilloirFrame.setZero();
303 constraintPosInBilloirFrame[0] = firstStartingPoint.
position() [0]-linPoint [0];
304 constraintPosInBilloirFrame[1] = firstStartingPoint.
position() [1]-linPoint [1];
305 constraintPosInBilloirFrame[2] = firstStartingPoint.
position() [2]-linPoint [2];
307 V_del += firstStartingPoint.covariancePosition().inverse() *constraintPosInBilloirFrame;
308 V_wgt_mat += firstStartingPoint.covariancePosition().inverse();
311 AmgMatrix(3,3) cov_delta_V_mat = V_wgt_mat.inverse().eval() ;
317 std::vector<
AmgMatrix(5,5)> cov_delta_P_mat ( nRP );
318 std::vector<double> chi2PerTrack;
319 chi2PerTrack.clear();
324 for ( BTIter = billoirTracks.begin(); BTIter != billoirTracks.end() ; ++BTIter )
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 )
332 if (msgLvl(MSG::WARNING))
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;
339 mom_at_Origin[iRP] ( 1 ) += delta_P[1];
340 if ( fabs ( mom_at_Origin[iRP] ( 0 ) ) > 5*
M_PI )
342 if (msgLvl(MSG::WARNING))
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;
349 mom_at_Origin[iRP] ( 2 ) += delta_P[2];
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 )
358 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;
362 if ( mom_at_Origin[iRP] ( 1 ) < 0.0 )
364 mom_at_Origin[iRP] ( 1 ) = - mom_at_Origin[iRP] ( 1 );
366 if ( mom_at_Origin[iRP] ( 0 ) >= 0 ) mom_at_Origin[iRP] ( 0 ) += ( mom_at_Origin[iRP] ( 0 ) >0 ) ? -
M_PI :
M_PI;
373 trans_mat ( 0,0 ) = locP.Di_mat ( 0,0 ); trans_mat ( 0,1 ) = locP.Di_mat ( 0,1 );
374 trans_mat ( 1,0 ) = locP.Di_mat ( 1,0 ); trans_mat ( 1,1 ) = locP.Di_mat ( 1,1 ); trans_mat ( 1,2 ) = 1.;
375 trans_mat ( 2,3 ) = 1.; trans_mat ( 3,4 ) = 1.; trans_mat ( 4,5 ) = 1.;
379 AmgMatrix(3,3) V_V_mat; V_V_mat.setZero(); V_V_mat = cov_delta_V_mat ;
382 AmgMatrix(3,3) V_P_mat; V_P_mat.setZero(); V_P_mat = -cov_delta_V_mat*locP.Gi_mat*locP.Ci_inv ;
385 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 ;
390 cov_mat.block<3,3>(0,3) = V_P_mat;
391 cov_mat.block<3,3>(3,0) = V_P_mat.transpose() ;
392 cov_mat.block<3,3>(0,0) = V_V_mat ;
393 cov_mat.block<3,3>(3,3) = P_P_mat ;
397 cov_delta_P_mat[iRP] = trans_mat*cov_mat*trans_mat.transpose() ;
403 ( *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];
405 if ( ( *BTIter ).chi2 < 0 )
407 ATH_MSG_WARNING(
"FullVertexFitter::calculate: error in chi2_per_track" );
410 chi2New += ( *BTIter ).chi2;
419 deltaTrk[0] = delta_V[0] - ( firstStartingPoint.
position() [0] - linPoint [0] );
420 deltaTrk[1] = delta_V[1] - ( firstStartingPoint.
position() [1] - linPoint [1] );
421 deltaTrk[2] = delta_V[2] - ( firstStartingPoint.
position() [2] - linPoint [2] );
422 chi2New += ( deltaTrk.transpose() * firstStartingPoint.covariancePosition().inverse() * deltaTrk ) [0];
427 tmpPos[0] += delta_V[0]; tmpPos[1] += delta_V[1]; tmpPos[2] += delta_V[2];
430 if ( chi2New <
chi2 )
452 tracksAtVertex.clear();
457 unsigned int iter= 0;
459 for ( BTIter = billoirTracks.begin(); BTIter != billoirTracks.end() ; ++BTIter )
461 const AmgMatrix(5,5) * newTrackCovarianceMatrix = &cov_delta_P_mat[iter] ;
464 AmgMatrix(5,5) newTrackErrorMatrix = (
AmgMatrix(5,5)) newTrackCovarianceMatrix->eval();
465 refittedPerigee =
new Trk::Perigee ( 0.,0.,mom_at_Origin[iter][0],mom_at_Origin[iter][1],mom_at_Origin[iter][2],
466 Surface, std::move(newTrackErrorMatrix) );
468 tracksAtVertex.push_back ( *tmpVxTrkAtVtx );
481 return fit ( perigeeList, tmpVtx );
494 return fit(vectorTrk, constraint);
500 if(vectorTrk.empty())
502 msg(MSG::INFO)<<
"Empty vector of tracks passed"<<
endmsg;
507 std::vector<const Trk::TrackParameters*> measuredPerigees;
509 for(
const auto *
i : vectorTrk)
513 if(tmpMeasPer!=
nullptr) measuredPerigees.push_back(tmpMeasPer);
514 else msg(MSG::INFO)<<
"Failed to dynamic_cast this track parameters to perigee"<<
endmsg;
526 for(
unsigned int i = 0;
i <vectorTrk.size(); ++
i)
541 for (
unsigned int i = 0 ;
i < VTAVsize ; ++
i)
546 ATH_MSG_WARNING (
" Trying to set link to xAOD::TrackParticle. The VxTrackAtVertex is not found");
561 ATH_MSG_WARNING (
"Skipping track. Trying to set link to something else than xAOD::TrackParticle. Neutrals not supported.");