137 const std::vector<const Trk::TrackParameters*> & originalPerigees,
140 if ( originalPerigees.empty() )
147 double chi2 = 2000000000000.;
148 unsigned int nRP = originalPerigees.size();
149 int ndf = nRP * ( 5-3 ) - 3;
150 if ( ndf < 0 ) {ndf = 1;}
153 bool constraint =
false;
154 if ( firstStartingPoint.covariancePosition().trace() != 0. )
168 std::vector<Amg::Vector3D> mom_at_Origin;
170 auto fittedVertex = std::make_unique<xAOD::Vertex>();
171 fittedVertex->makePrivateStore();
173 std::vector<VxTrackAtVertex> tracksAtVertex;
174 std::vector<BilloirTrack> billoirTracks;
181 << linPoint [0] <<
", " << linPoint [1] <<
", " << linPoint [2]
182 <<
") and " << originalPerigees.size() <<
" tracks.");
184 billoirTracks.clear();
188 BilloirVertex billoirVertex;
195 unsigned int count(0);
196 for (
const auto *originalPerigee : originalPerigees)
204 if ( chargedParameters==
nullptr )
206 ATH_MSG_ERROR(
"Track parameters are not charged tracks ... full fit aborted (this will be handled correctly soon)");
211 p0.x() = chargedParameters->parameters() [
Trk::phi];
212 p0.y() = chargedParameters->parameters() [
Trk::theta];
213 p0.z() = chargedParameters->parameters() [
Trk::qOverP] ;
214 mom_at_Origin.push_back ( p0 );
224 std::unique_ptr<LinearizedTrack> linTrack (
m_linFactory->linearizedTrack ( originalPerigee, linPoint ) );
225 if ( linTrack==
nullptr )
227 ATH_MSG_DEBUG(
"Could not linearize track! Skipping this track!");
231 BilloirTrack locBilloirTrack;
233 locBilloirTrack.originalPerigee = originalPerigee;
234 double d0 = linTrack->expectedParametersAtPCA()[
Trk::d0];
235 double z0 = linTrack->expectedParametersAtPCA()[
Trk::z0];
236 double phi = linTrack->expectedParametersAtPCA()[
Trk::phi];
241 double f_phi = mom_at_Origin[
count] ( 0 );
242 double f_theta = mom_at_Origin[
count] ( 1 );
243 double f_qOverP = mom_at_Origin[
count] ( 2 );
246 locBilloirTrack.Dper[0] =
d0;
247 locBilloirTrack.Dper[1] =
z0;
248 locBilloirTrack.Dper[2] =
phi - f_phi;
249 locBilloirTrack.Dper[3] =
theta - f_theta;
250 locBilloirTrack.Dper[4] =
qOverP -f_qOverP;
255 D_mat = linTrack->positionJacobian();
260 E_mat = linTrack->momentumJacobian();
267 Dt_W_mat = D_mat.transpose() * ( linTrack->expectedWeightAtPCA() );
268 Et_W_mat = E_mat.transpose() * ( linTrack->expectedWeightAtPCA() );
271 locBilloirTrack.Di_mat = D_mat;
272 locBilloirTrack.Ei_mat = E_mat;
273 locBilloirTrack.Gi_mat = Et_W_mat*E_mat;
274 locBilloirTrack.Bi_mat = Dt_W_mat * E_mat;
275 locBilloirTrack.Ui_vec = Et_W_mat * locBilloirTrack.Dper;
276 locBilloirTrack.Ci_inv = Et_W_mat * E_mat ;
278 locBilloirTrack.Ci_inv = locBilloirTrack.Ci_inv.inverse().eval();
280 billoirVertex.T_vec += Dt_W_mat * locBilloirTrack.Dper;
281 billoirVertex.A_mat = billoirVertex.A_mat + Dt_W_mat * D_mat ;
284 locBilloirTrack.BCi_mat = locBilloirTrack.Bi_mat * locBilloirTrack.Ci_inv;
287 billoirVertex.BCU_vec += locBilloirTrack.BCi_mat * locBilloirTrack.Ui_vec;
288 billoirVertex.BCB_mat = billoirVertex.BCB_mat + locBilloirTrack.BCi_mat * locBilloirTrack.Bi_mat.transpose() ;
289 locBilloirTrack.linTrack = std::move(linTrack);
290 billoirTracks.push_back ( std::move(locBilloirTrack) );
297 Amg::Vector3D V_del = billoirVertex.T_vec - billoirVertex.BCU_vec;
298 AmgMatrix(3,3) V_wgt_mat = billoirVertex.A_mat - billoirVertex.BCB_mat;
304 constraintPosInBilloirFrame.setZero();
306 constraintPosInBilloirFrame[0] = firstStartingPoint.
position() [0]-linPoint [0];
307 constraintPosInBilloirFrame[1] = firstStartingPoint.
position() [1]-linPoint [1];
308 constraintPosInBilloirFrame[2] = firstStartingPoint.
position() [2]-linPoint [2];
310 V_del += firstStartingPoint.covariancePosition().inverse() *constraintPosInBilloirFrame;
311 V_wgt_mat += firstStartingPoint.covariancePosition().inverse();
314 AmgMatrix(3,3) cov_delta_V_mat = V_wgt_mat.inverse().eval() ;
320 std::vector<
AmgMatrix(5,5)> cov_delta_P_mat ( nRP );
321 std::vector<double> chi2PerTrack;
322 chi2PerTrack.clear();
325 std::vector<BilloirTrack>::iterator BTIter;
327 for ( BTIter = billoirTracks.begin(); BTIter != billoirTracks.end() ; ++BTIter )
330 BilloirTrack locP ( ( *BTIter ) );
331 Amg::Vector3D delta_P = ( locP.Ci_inv ) * ( ( locP.Ui_vec )- ( locP.Bi_mat.transpose() ) *delta_V );
332 mom_at_Origin[iRP] ( 0 ) += delta_P[0];
333 if ( fabs ( mom_at_Origin[iRP] ( 0 ) ) > 10*
M_PI )
335 if (msgLvl(MSG::WARNING))
337 msg(MSG::WARNING) <<
" Track direction angles have numerical problems, stop perigee parameter update." <<
endmsg;
338 msg(MSG::WARNING) <<
" Phi value: "<<mom_at_Origin[iRP] ( 0 ) <<
endmsg;
342 mom_at_Origin[iRP] ( 1 ) += delta_P[1];
343 if ( fabs ( mom_at_Origin[iRP] ( 0 ) ) > 5*
M_PI )
345 if (msgLvl(MSG::WARNING))
347 msg(MSG::WARNING) <<
" Track direction angles have numerical problems, stop perigee parameter update." <<
endmsg;
348 msg(MSG::WARNING) <<
" Theta value: "<<mom_at_Origin[iRP] ( 1 ) <<
endmsg;
352 mom_at_Origin[iRP] ( 2 ) += delta_P[2];
356 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;
357 while ( mom_at_Origin[iRP] ( 1 ) > 2*
M_PI ) mom_at_Origin[iRP] ( 1 ) -= 2*
M_PI;
358 while ( mom_at_Origin[iRP] ( 1 ) < -
M_PI ) mom_at_Origin[iRP] ( 1 ) +=
M_PI;
359 if ( mom_at_Origin[iRP] ( 1 ) >
M_PI )
361 mom_at_Origin[iRP] ( 1 ) = 2*
M_PI - mom_at_Origin[iRP] ( 1 );
362 if ( mom_at_Origin[iRP] ( 0 ) >= 0 ) mom_at_Origin[iRP] ( 0 ) += ( mom_at_Origin[iRP] ( 0 ) >0 ) ? -
M_PI :
M_PI;
364 if ( mom_at_Origin[iRP] ( 1 ) < 0.0 )
366 mom_at_Origin[iRP] ( 1 ) = - mom_at_Origin[iRP] ( 1 );
367 if ( mom_at_Origin[iRP] ( 0 ) >= 0 ) mom_at_Origin[iRP] ( 0 ) += ( mom_at_Origin[iRP] ( 0 ) >0 ) ? -
M_PI :
M_PI;
374 trans_mat ( 0,0 ) = locP.Di_mat ( 0,0 ); trans_mat ( 0,1 ) = locP.Di_mat ( 0,1 );
375 trans_mat ( 1,0 ) = locP.Di_mat ( 1,0 ); trans_mat ( 1,1 ) = locP.Di_mat ( 1,1 ); trans_mat ( 1,2 ) = 1.;
376 trans_mat ( 2,3 ) = 1.; trans_mat ( 3,4 ) = 1.; trans_mat ( 4,5 ) = 1.;
380 AmgMatrix(3,3) V_V_mat; V_V_mat.setZero(); V_V_mat = cov_delta_V_mat ;
383 AmgMatrix(3,3) V_P_mat; V_P_mat.setZero(); V_P_mat = -cov_delta_V_mat*locP.Gi_mat*locP.Ci_inv ;
386 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 ;
391 cov_mat.block<3,3>(0,3) = V_P_mat;
392 cov_mat.block<3,3>(3,0) = V_P_mat.transpose() ;
393 cov_mat.block<3,3>(0,0) = V_V_mat ;
394 cov_mat.block<3,3>(3,3) = P_P_mat ;
398 cov_delta_P_mat[iRP] = trans_mat*cov_mat*trans_mat.transpose() ;
404 ( *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];
406 if ( ( *BTIter ).chi2 < 0 )
408 ATH_MSG_WARNING(
"FullVertexFitter::calculate: error in chi2_per_track" );
411 chi2New += ( *BTIter ).chi2;
420 deltaTrk[0] = delta_V[0] - ( firstStartingPoint.
position() [0] - linPoint [0] );
421 deltaTrk[1] = delta_V[1] - ( firstStartingPoint.
position() [1] - linPoint [1] );
422 deltaTrk[2] = delta_V[2] - ( firstStartingPoint.
position() [2] - linPoint [2] );
423 chi2New += ( deltaTrk.transpose() * firstStartingPoint.covariancePosition().inverse() * deltaTrk ) [0];
428 tmpPos[0] += delta_V[0]; tmpPos[1] += delta_V[1]; tmpPos[2] += delta_V[2];
431 if ( chi2New <
chi2 )
440 fittedVertex->setPosition( linPoint );
441 fittedVertex->setCovariancePosition( cov_delta_V_mat );
442 fittedVertex->setFitQuality(
chi2, ndf );
453 tracksAtVertex.clear();
458 unsigned int iter= 0;
459 std::vector<BilloirTrack>::iterator BTIter;
460 for ( BTIter = billoirTracks.begin(); BTIter != billoirTracks.end() ; ++BTIter )
462 const AmgMatrix(5,5) * newTrackCovarianceMatrix = &cov_delta_P_mat[iter] ;
465 AmgMatrix(5,5) newTrackErrorMatrix = (
AmgMatrix(5,5)) newTrackCovarianceMatrix->eval();
466 refittedPerigee =
new Trk::Perigee ( 0.,0.,mom_at_Origin[iter][0],mom_at_Origin[iter][1],mom_at_Origin[iter][2],
467 Surface, std::move(newTrackErrorMatrix) );
469 tracksAtVertex.push_back ( *tmpVxTrkAtVtx );
474 fittedVertex->vxTrackAtVertex() = tracksAtVertex;