138 if ( originalPerigees.empty() )
145 double chi2 = 2000000000000.;
146 unsigned int nRP = originalPerigees.size();
147 int ndf = nRP * ( 5-3 ) - 3;
148 if ( ndf < 0 ) {ndf = 1;}
151 bool constraint =
false;
152 if ( firstStartingPoint.covariancePosition().trace() != 0. )
166 std::vector<Amg::Vector3D> mom_at_Origin;
171 std::vector<VxTrackAtVertex> tracksAtVertex;
172 std::vector<BilloirTrack> billoirTracks;
179 << linPoint [0] <<
", " << linPoint [1] <<
", " << linPoint [2]
180 <<
") and " << originalPerigees.size() <<
" tracks.");
182 billoirTracks.clear();
186 BilloirVertex billoirVertex;
193 unsigned int count(0);
194 for (
const auto *originalPerigee : originalPerigees)
202 if ( chargedParameters==
nullptr )
204 ATH_MSG_ERROR(
"Track parameters are not charged tracks ... full fit aborted (this will be handled correctly soon)");
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 );
222 std::unique_ptr<LinearizedTrack> linTrack (
m_linFactory->linearizedTrack ( originalPerigee, linPoint ) );
223 if ( linTrack==
nullptr )
225 ATH_MSG_DEBUG(
"Could not linearize track! Skipping this track!");
229 BilloirTrack locBilloirTrack;
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];
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 locBilloirTrack.linTrack = std::move(linTrack);
288 billoirTracks.push_back ( std::move(locBilloirTrack) );
295 Amg::Vector3D V_del = billoirVertex.T_vec - billoirVertex.BCU_vec;
296 AmgMatrix(3,3) V_wgt_mat = billoirVertex.A_mat - billoirVertex.BCB_mat;
302 constraintPosInBilloirFrame.setZero();
304 constraintPosInBilloirFrame[0] = firstStartingPoint.
position() [0]-linPoint [0];
305 constraintPosInBilloirFrame[1] = firstStartingPoint.
position() [1]-linPoint [1];
306 constraintPosInBilloirFrame[2] = firstStartingPoint.
position() [2]-linPoint [2];
308 V_del += firstStartingPoint.covariancePosition().inverse() *constraintPosInBilloirFrame;
309 V_wgt_mat += firstStartingPoint.covariancePosition().inverse();
312 AmgMatrix(3,3) cov_delta_V_mat = V_wgt_mat.inverse().eval() ;
318 std::vector<
AmgMatrix(5,5)> cov_delta_P_mat ( nRP );
319 std::vector<double> chi2PerTrack;
320 chi2PerTrack.clear();
323 std::vector<BilloirTrack>::iterator BTIter;
325 for ( BTIter = billoirTracks.begin(); BTIter != billoirTracks.end() ; ++BTIter )
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 )
333 if (msgLvl(MSG::WARNING))
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;
340 mom_at_Origin[iRP] ( 1 ) += delta_P[1];
341 if ( fabs ( mom_at_Origin[iRP] ( 0 ) ) > 5*
M_PI )
343 if (msgLvl(MSG::WARNING))
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;
350 mom_at_Origin[iRP] ( 2 ) += delta_P[2];
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 )
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;
362 if ( mom_at_Origin[iRP] ( 1 ) < 0.0 )
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;
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.;
378 AmgMatrix(3,3) V_V_mat; V_V_mat.setZero(); V_V_mat = cov_delta_V_mat ;
381 AmgMatrix(3,3) V_P_mat; V_P_mat.setZero(); V_P_mat = -cov_delta_V_mat*locP.Gi_mat*locP.Ci_inv ;
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 ;
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 ;
396 cov_delta_P_mat[iRP] = trans_mat*cov_mat*trans_mat.transpose() ;
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];
404 if ( ( *BTIter ).chi2 < 0 )
406 ATH_MSG_WARNING(
"FullVertexFitter::calculate: error in chi2_per_track" );
409 chi2New += ( *BTIter ).chi2;
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];
426 tmpPos[0] += delta_V[0]; tmpPos[1] += delta_V[1]; tmpPos[2] += delta_V[2];
429 if ( chi2New <
chi2 )
451 tracksAtVertex.clear();
456 unsigned int iter= 0;
457 std::vector<BilloirTrack>::iterator BTIter;
458 for ( BTIter = billoirTracks.begin(); BTIter != billoirTracks.end() ; ++BTIter )
460 const AmgMatrix(5,5) * newTrackCovarianceMatrix = &cov_delta_P_mat[iter] ;
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) );
467 tracksAtVertex.push_back ( *tmpVxTrkAtVtx );