233 const std::vector<const Trk::TrackParameters*>& originalPerigees,
234 const std::vector<double>& masses,
235 const double& constraintMass,
239 if ( originalPerigees.empty() )
246 bool pointingConstraint =
false;
247 bool massConstraint =
false;
248 if(constraintMass > -100.) massConstraint =
true;
249 bool conversion =
false;
250 if(constraintMass == 0. && originalPerigees.size() == 2) conversion =
true;
251 double x_point=0., y_point=0., z_point=0.;
252 AmgSymMatrix(3) pointingVertexCov; pointingVertexCov.setIdentity();
253 if (pointingVertex !=
nullptr) {
254 if (pointingVertex->covariancePosition().trace() != 0.) {
255 pointingConstraint =
true;
260 pointingVertexCov = pointingVertex->covariancePosition().inverse();
264 if (msgLvl(MSG::DEBUG)) {
265 msg(MSG::DEBUG) <<
"massConstraint " << massConstraint <<
" pointingConstraint " << pointingConstraint <<
" conversion " << conversion <<
endmsg;
266 msg(MSG::DEBUG) <<
"V0Fitter called with: " <<
endmsg;
267 if (massConstraint && !masses.empty())
msg(MSG::DEBUG) <<
"mass constraint, V0Mass = " << constraintMass <<
" particle masses " << masses <<
endmsg;
268 if (pointingConstraint)
msg(MSG::DEBUG) <<
"pointing constraint, x = " << x_point <<
" y = " << y_point <<
" z = " << z_point <<
endmsg;
271 bool restartFit =
true;
272 double chi2 = 2000000000000.;
273 unsigned int nTrk = originalPerigees.size();
274 unsigned int nMeas = 5*nTrk;
275 unsigned int nVert = 1;
277 unsigned int nCnst = 2*nTrk;
278 unsigned int nPntC = 2;
279 unsigned int nMass = 1;
281 if (massConstraint) {
282 nCnst = nCnst + nMass;
284 if (pointingConstraint) {
285 nCnst = nCnst + nPntC;
290 unsigned int nPar = 5*nTrk + 3*nVert;
291 int ndf = nMeas - (nPar - nCnst);
292 if (ndf < 0) {ndf = 1;}
294 unsigned int dim = nCnst;
295 unsigned int n_dim = nMeas;
297 ATH_MSG_DEBUG(
"ndf " << ndf <<
" n_dim " << n_dim <<
" dim " << dim);
299 std::vector<V0FitterTrack> v0FitterTracks;
305 Amg::MatrixX Wmeas_mat(n_dim,n_dim); Wmeas_mat.setZero();
306 Amg::MatrixX Wmeas0_mat(n_dim,n_dim); Wmeas0_mat.setZero();
330 const Amg::Vector3D * globalPosition = &(firstStartingPoint);
331 ATH_MSG_DEBUG(
"globalPosition of starting point: " << (*globalPosition)[0] <<
", " << (*globalPosition)[1] <<
", " << (*globalPosition)[2]);
333 if (globalPosition->perp() >
m_maxR && globalPosition->z() >
m_maxZ)
return nullptr;
337 std::string
msg =
"Failed to retrieve magmnetic field conditions data ";
339 throw std::runtime_error(
msg);
351 fieldCache.
getField(globalPosition->data(),BField);
352 double B_z = BField[2]*299.792;
353 if (B_z == 0. || std::isnan(B_z)) {
354 ATH_MSG_DEBUG(
"Could not find a magnetic field different from zero: very very strange");
357 ATH_MSG_VERBOSE(
"Magnetic field projection of z axis in the perigee position is: " << B_z <<
" GeV/mm ");
362 v0FitterTracks.clear();
367 if (chargeParameters !=
nullptr)
370 const Amg::Vector3D gMomentum = chargeParameters->momentum();
371 const Amg::Vector3D gDirection = chargeParameters->position() - *globalPosition;
372 const double extrapolationDirection = gMomentum.dot( gDirection );
375 std::unique_ptr<const Trk::Perigee> extrapolatedPerigee(
nullptr);
377 std::unique_ptr<const Trk::TrackParameters> tmp =
378 std::abs(chargeParameters->position().z()) >
m_maxZ ? nullptr :
389 extrapolatedPerigee.reset(
static_cast<const Trk::Perigee*
>(tmp.release()));
392 if (extrapolatedPerigee ==
nullptr) {
393 ATH_MSG_DEBUG(
"Perigee was not extrapolated! Taking original one!");
395 if (tmpPerigee!=
nullptr) extrapolatedPerigee = std::make_unique<Trk::Perigee>(*tmpPerigee);
400 V0FitterTrack locV0FitterTrack{};
401 locV0FitterTrack.TrkPar[0] = extrapolatedPerigee->parameters()[
Trk::d0];
402 locV0FitterTrack.TrkPar[1] = extrapolatedPerigee->parameters()[
Trk::z0];
403 locV0FitterTrack.TrkPar[2] = extrapolatedPerigee->parameters()[
Trk::phi];
404 locV0FitterTrack.TrkPar[3] = extrapolatedPerigee->parameters()[
Trk::theta];
405 locV0FitterTrack.TrkPar[4] = extrapolatedPerigee->parameters()[
Trk::qOverP];
406 locV0FitterTrack.Wi_mat = extrapolatedPerigee->covariance()->inverse().eval();
407 locV0FitterTrack.originalPerigee = chargeParameters;
408 v0FitterTracks.push_back(locV0FitterTrack);
410 ATH_MSG_DEBUG(
"Track parameters are not charged tracks ... fit aborted");
416 double chi2New=0.;
double chi2Old=
chi2;
418 bool onConstr =
false;
424 if (!restartFit) chi2Old = chi2New;
430 std::vector<V0FitterTrack>::iterator PTIter;
432 for (PTIter = v0FitterTracks.begin(); PTIter != v0FitterTracks.end() ; ++PTIter)
434 V0FitterTrack locP((*PTIter));
435 Wmeas0_mat.block<5,5>(5*i,5*i) = locP.Wi_mat;
436 Wmeas_mat.block<5,5>(5*i,5*i) = locP.Wi_mat;
437 for (
int j=0; j<5; ++j) {
438 Y0_vec(j+5*i) = locP.TrkPar[j];
442 if(pointingConstraint) {
443 Y0_vec(5*nTrk + 0) = x_point;
444 Y0_vec(5*nTrk + 1) = y_point;
445 Y0_vec(5*nTrk + 2) = z_point;
446 Wmeas0_mat.block<3,3>(5*nTrk,5*nTrk) = pointingVertexCov;
447 Wmeas_mat.block<3,3>(5*nTrk,5*nTrk) = pointingVertexCov;
449 Wmeas_mat = Wmeas_mat.inverse();
452 Y_vec = Y0_vec + DeltaY_vec;
456 for (
unsigned int i=0; i<nTrk; ++i)
458 if ( fabs ( Y_vec(2+5*i) ) > 100. || fabs ( Y_vec(3+5*i) ) > 100. ) {
return nullptr; }
459 while ( fabs ( Y_vec(2+5*i) ) >
M_PI ) Y_vec(2+5*i) += ( Y_vec(2+5*i) > 0 ) ? -2*
M_PI : 2*
M_PI;
460 while ( Y_vec(3+5*i) > 2*
M_PI ) Y_vec(3+5*i) -= 2*
M_PI;
461 while ( Y_vec(3+5*i) < -
M_PI ) Y_vec(3+5*i) +=
M_PI;
462 if ( Y_vec(3+5*i) >
M_PI )
464 Y_vec(3+5*i) = 2*
M_PI - Y_vec(3+5*i);
465 if ( Y_vec(2+5*i) >= 0 ) Y_vec(2+5*i) += ( Y_vec(2+5*i) >0 ) ? -
M_PI :
M_PI;
467 if ( Y_vec(3+5*i) < 0.0 )
469 Y_vec(3+5*i) = - Y_vec(3+5*i);
470 if ( Y_vec(2+5*i) >= 0 ) Y_vec(2+5*i) += ( Y_vec(2+5*i) >0 ) ? -
M_PI :
M_PI;
474 double SigE=0., SigPx=0., SigPy=0., SigPz=0., Px=0., Py=0., Pz=0.;
476 rho.setZero(); Phi.setZero();
charge.setZero();
477 Amg::VectorX d0Cor(nTrk), d0Fac(nTrk), xcphiplusysphi(nTrk), xsphiminusycphi(nTrk);
478 d0Cor.setZero(); d0Fac.setZero(); xcphiplusysphi.setZero(); xsphiminusycphi.setZero();
480 conv_sign[0] = -1; conv_sign[1] = 1;
481 for (
unsigned int i=0; i<nTrk; ++i)
483 charge[i] = (Y_vec(4+5*i) < 0.) ? -1. : 1.;
484 rho[i] = sin(Y_vec(3+5*i))/(B_z*Y_vec(4+5*i));
485 xcphiplusysphi[i] = A_vec(0)*cos(Y_vec(2+5*i))+A_vec(1)*sin(Y_vec(2+5*i));
486 xsphiminusycphi[i] = A_vec(0)*sin(Y_vec(2+5*i))-A_vec(1)*cos(Y_vec(2+5*i));
487 if(fabs(-xcphiplusysphi[i]/rho[i]) > 1.)
return nullptr;
488 d0Cor[i] = 0.5*asin(-xcphiplusysphi[i]/rho[i]);
489 double d0Facsq = 1. - xcphiplusysphi[i]*xcphiplusysphi[i]/(rho[i]*rho[i]);
490 d0Fac[i] = (d0Facsq>0.) ? sqrt(d0Facsq) : 0;
491 Phi[i] = Y_vec(2+5*i) + 2.*d0Cor[i];
493 if(massConstraint && !masses.empty() && masses[i] != 0.){
494 SigE += sqrt(1./(Y_vec(4+5*i)*Y_vec(4+5*i)) + masses[i]*masses[i]);
495 SigPx += sin(Y_vec(3+5*i))*cos(Y_vec(2+5*i))*
charge[i]/Y_vec(4+5*i);
496 SigPy += sin(Y_vec(3+5*i))*sin(Y_vec(2+5*i))*
charge[i]/Y_vec(4+5*i);
497 SigPz += cos(Y_vec(3+5*i))*
charge[i]/Y_vec(4+5*i);
499 Px += sin(Y_vec(3+5*i))*cos(Y_vec(2+5*i))*
charge[i]/Y_vec(4+5*i);
500 Py += sin(Y_vec(3+5*i))*sin(Y_vec(2+5*i))*
charge[i]/Y_vec(4+5*i);
501 Pz += cos(Y_vec(3+5*i))*
charge[i]/Y_vec(4+5*i);
504 double FMass=0., dFMassdxs=0., dFMassdys=0., dFMassdzs=0.;
505 double FPxy=0., dFPxydxs=0., dFPxydys=0., dFPxydzs=0., dFPxydxp=0., dFPxydyp=0., dFPxydzp=0.;
506 double FPxz=0., dFPxzdxs=0., dFPxzdys=0., dFPxzdzs=0., dFPxzdxp=0., dFPxzdyp=0., dFPxzdzp=0.;
508 Fxy.setZero(); Fxz.setZero(); dFMassdPhi.setZero();
509 Amg::VectorX drhodtheta(nTrk), drhodqOverP(nTrk), csplusbc(nTrk), ccminusbs(nTrk);
510 drhodtheta.setZero(); drhodqOverP.setZero(); csplusbc.setZero(); ccminusbs.setZero();
511 Amg::VectorX dFxydd0(nTrk), dFxydz0(nTrk), dFxydphi(nTrk), dFxydtheta(nTrk), dFxydqOverP(nTrk);
512 dFxydd0.setZero(); dFxydz0.setZero(); dFxydphi.setZero(); dFxydtheta.setZero(); dFxydqOverP.setZero();
513 Amg::VectorX dFxydxs(nTrk), dFxydys(nTrk), dFxydzs(nTrk);
514 dFxydxs.setZero(); dFxydys.setZero(); dFxydzs.setZero();
515 Amg::VectorX dFxzdd0(nTrk), dFxzdz0(nTrk), dFxzdphi(nTrk), dFxzdtheta(nTrk), dFxzdqOverP(nTrk);
516 dFxzdd0.setZero(); dFxzdz0.setZero(); dFxzdphi.setZero(); dFxzdtheta.setZero(); dFxzdqOverP.setZero();
517 Amg::VectorX dFxzdxs(nTrk), dFxzdys(nTrk), dFxzdzs(nTrk);
518 dFxzdxs.setZero(); dFxzdys.setZero(); dFxzdzs.setZero();
519 Amg::VectorX dFMassdd0(nTrk), dFMassdz0(nTrk), dFMassdphi(nTrk), dFMassdtheta(nTrk), dFMassdqOverP(nTrk);
520 dFMassdd0.setZero(); dFMassdz0.setZero(); dFMassdphi.setZero(); dFMassdtheta.setZero(); dFMassdqOverP.setZero();
521 Amg::VectorX dFPxydd0(nTrk), dFPxydz0(nTrk), dFPxydphi(nTrk), dFPxydtheta(nTrk), dFPxydqOverP(nTrk);
522 dFPxydd0.setZero(); dFPxydz0.setZero(); dFPxydphi.setZero(); dFPxydtheta.setZero(); dFPxydqOverP.setZero();
523 Amg::VectorX dFPxzdd0(nTrk), dFPxzdz0(nTrk), dFPxzdphi(nTrk), dFPxzdtheta(nTrk), dFPxzdqOverP(nTrk);
524 dFPxzdd0.setZero(); dFPxzdz0.setZero(); dFPxzdphi.setZero(); dFPxzdtheta.setZero(); dFPxzdqOverP.setZero();
525 Amg::VectorX dPhidd0(nTrk), dPhidz0(nTrk), dPhidphi0(nTrk), dPhidtheta(nTrk), dPhidqOverP(nTrk);
526 dPhidd0.setZero(); dPhidz0.setZero(); dPhidphi0.setZero(); dPhidtheta.setZero(); dPhidqOverP.setZero();
527 Amg::VectorX dPhidxs(nTrk), dPhidys(nTrk), dPhidzs(nTrk);
528 dPhidxs.setZero(); dPhidys.setZero(); dPhidzs.setZero();
535 FMass = Phi[1] - Phi[0];
537 FMass = constraintMass*constraintMass - SigE*SigE + SigPx*SigPx + SigPy*SigPy + SigPz*SigPz;
542 FPxy = Px*(frameOriginItr[1] - y_point) - Py*(frameOriginItr[0]- x_point);
546 FPxz = Px*(frameOriginItr[2] - z_point) - Pz*(frameOriginItr[0]- x_point);
548 for (
unsigned int i=0; i<nTrk; ++i)
553 Fxy[i] = Y_vec(0+5*i) + xsphiminusycphi[i] - 2.*rho[i]*sin(d0Cor[i])*sin(d0Cor[i]);
557 Fxz[i] = Y_vec(1+5*i) - A_vec(2) - rho[i]*2.*d0Cor[i]/tan(Y_vec(3+5*i));
561 drhodtheta[i] = cos(Y_vec(3+5*i))/(B_z*Y_vec(4+5*i));
562 drhodqOverP[i] = -sin(Y_vec(3+5*i))/(B_z*Y_vec(4+5*i)*Y_vec(4+5*i));
565 dFxydphi[i] = xcphiplusysphi[i]*(1. + xsphiminusycphi[i]/(d0Fac[i]*rho[i]));
566 dFxydtheta[i] = (xcphiplusysphi[i]*xcphiplusysphi[i]/(d0Fac[i]*rho[i]*rho[i])-2.*sin(d0Cor[i])*sin(d0Cor[i]))*drhodtheta[i];
567 dFxydqOverP[i] = (xcphiplusysphi[i]*xcphiplusysphi[i]/(d0Fac[i]*rho[i]*rho[i])-2.*sin(d0Cor[i])*sin(d0Cor[i]))*drhodqOverP[i];
568 dFxydxs[i] = sin(Y_vec(2+5*i)) - cos(Y_vec(2+5*i))*xcphiplusysphi[i]/(d0Fac[i]*rho[i]);
569 dFxydys[i] = -cos(Y_vec(2+5*i)) - sin(Y_vec(2+5*i))*xcphiplusysphi[i]/(d0Fac[i]*rho[i]);
572 dFxzdphi[i] = -xsphiminusycphi[i]/(d0Fac[i]*tan(Y_vec(3+5*i)));
573 dFxzdtheta[i] = -((xcphiplusysphi[i]/(d0Fac[i]*rho[i]) + 2.*d0Cor[i])*tan(Y_vec(3+5*i))*drhodtheta[i] -
574 rho[i]*2.*d0Cor[i]/(cos(Y_vec(3+5*i))*cos(Y_vec(3+5*i))))/(tan(Y_vec(3+5*i))*tan(Y_vec(3+5*i)));
575 dFxzdqOverP[i] = -(xcphiplusysphi[i]/(d0Fac[i]*rho[i]) + 2.*d0Cor[i])*drhodqOverP[i]/tan(Y_vec(3+5*i));
576 dFxzdxs[i] = cos(Y_vec(2+5*i))/(d0Fac[i]*tan(Y_vec(3+5*i)));
577 dFxzdys[i] = sin(Y_vec(2+5*i))/(d0Fac[i]*tan(Y_vec(3+5*i)));
580 dPhidphi0[i] = 1. + xsphiminusycphi[i]/(d0Fac[i]*rho[i]);
581 dPhidtheta[i] = xcphiplusysphi[i]*drhodtheta[i]/(d0Fac[i]*rho[i]*rho[i]);
582 dPhidqOverP[i] = xcphiplusysphi[i]*drhodqOverP[i]/(d0Fac[i]*rho[i]*rho[i]);
583 dPhidxs[i] = -cos(Y_vec(2+5*i))/(d0Fac[i]*rho[i]);
584 dPhidys[i] = -sin(Y_vec(2+5*i))/(d0Fac[i]*rho[i]);
586 if (massConstraint && !masses.empty() && masses[i] != 0.){
588 dFMassdphi[i] = conv_sign[i]*dPhidphi0[i];
589 dFMassdtheta[i] = conv_sign[i]*dPhidtheta[i];
590 dFMassdqOverP[i] = conv_sign[i]*dPhidqOverP[i];
591 dFMassdxs += conv_sign[i]*dPhidxs[i];
592 dFMassdys += conv_sign[i]*dPhidys[i];
594 csplusbc[i] = SigPy*sin(Y_vec(2+5*i))+SigPx*cos(Y_vec(2+5*i));
595 ccminusbs[i] = SigPy*cos(Y_vec(2+5*i))-SigPx*sin(Y_vec(2+5*i));
596 dFMassdphi[i] = 2.*sin(Y_vec(3+5*i))*ccminusbs[i]*
charge[i]/Y_vec(4+5*i);
597 dFMassdtheta[i] = 2.*(cos(Y_vec(3+5*i))*csplusbc[i] - sin(Y_vec(3+5*i))*SigPz)*
charge[i]/Y_vec(4+5*i);
598 dFMassdqOverP[i] = 2.*SigE/(sqrt(1./(Y_vec(4+5*i)*Y_vec(4+5*i)) + masses[i]*masses[i])*Y_vec(4+5*i)*Y_vec(4+5*i)*Y_vec(4+5*i)) -
599 2.*
charge[i]*(sin(Y_vec(3+5*i))*csplusbc[i] + cos(Y_vec(3+5*i))*SigPz)/(Y_vec(4+5*i)*Y_vec(4+5*i));
603 if (pointingConstraint){
604 dFPxydphi[i] = -sin(Y_vec(3+5*i))*(sin(Y_vec(2+5*i))*(frameOriginItr[1]-y_point)+cos(Y_vec(2+5*i))*(frameOriginItr[0]-x_point))*
charge[i]/Y_vec(4+5*i);
605 dFPxydtheta[i] = cos(Y_vec(3+5*i))*(cos(Y_vec(2+5*i))*(frameOriginItr[1]-y_point)-sin(Y_vec(2+5*i))*(frameOriginItr[0]-x_point))*
charge[i]/Y_vec(4+5*i);
606 dFPxydqOverP[i] = -sin(Y_vec(3+5*i))*(cos(Y_vec(2+5*i))*(frameOriginItr[1]-y_point)-sin(Y_vec(2+5*i))*(frameOriginItr[0]-x_point))*
charge[i]/(Y_vec(4+5*i)*Y_vec(4+5*i));
607 dFPxydxs += -sin(Y_vec(3+5*i))*sin(Y_vec(2+5*i))*
charge[i]/Y_vec(4+5*i);
608 dFPxydys += sin(Y_vec(3+5*i))*cos(Y_vec(2+5*i))*
charge[i]/Y_vec(4+5*i);
609 dFPxydxp += sin(Y_vec(3+5*i))*sin(Y_vec(2+5*i))*
charge[i]/Y_vec(4+5*i);
610 dFPxydyp += -sin(Y_vec(3+5*i))*cos(Y_vec(2+5*i))*
charge[i]/Y_vec(4+5*i);
612 dFPxzdphi[i] = -sin(Y_vec(3+5*i))*sin(Y_vec(2+5*i))*(frameOriginItr[2]-z_point)*
charge[i]/Y_vec(4+5*i);
613 dFPxzdtheta[i] = cos(Y_vec(3+5*i))*cos(Y_vec(2+5*i))*(frameOriginItr[2]-z_point)*
charge[i]/Y_vec(4+5*i)
614 +sin(Y_vec(3+5*i))*(frameOriginItr[0]-x_point)*
charge[i]/Y_vec(4+5*i);
615 dFPxzdqOverP[i] = -sin(Y_vec(3+5*i))*cos(Y_vec(2+5*i))*(frameOriginItr[2]-z_point)*
charge[i]/(Y_vec(4+5*i)*Y_vec(4+5*i))
616 +cos(Y_vec(3+5*i))*(frameOriginItr[0]-x_point)*
charge[i]/(Y_vec(4+5*i)*Y_vec(4+5*i));
617 dFPxzdxs += -cos(Y_vec(3+5*i))*
charge[i]/Y_vec(4+5*i);
618 dFPxzdzs += sin(Y_vec(3+5*i))*cos(Y_vec(2+5*i))*
charge[i]/Y_vec(4+5*i);
619 dFPxzdxp += cos(Y_vec(3+5*i))*
charge[i]/Y_vec(4+5*i);
620 dFPxzdzp += -sin(Y_vec(3+5*i))*cos(Y_vec(2+5*i))*
charge[i]/Y_vec(4+5*i);
625 F_vec[i+nTrk] = -Fxz[i];
627 F_fac_vec[i+nTrk] = 1.;
629 if(massConstraint) F_vec(2*nTrk+0) = -FMass;
631 if(massConstraint) F_fac_vec(2*nTrk+0) = 0.000001;
632 if(pointingConstraint) {
634 F_vec(2*nTrk+1) = -FPxy;
635 F_vec(2*nTrk+2) = -FPxz;
636 F_fac_vec(2*nTrk+1) = 0.000001;
637 F_fac_vec(2*nTrk+2) = 0.000001;
639 F_vec(2*nTrk+0) = -FPxy;
640 F_vec(2*nTrk+1) = -FPxz;
641 F_fac_vec(2*nTrk+0) = 0.000001;
642 F_fac_vec(2*nTrk+1) = 0.000001;
647 for (
unsigned int i=0; i<dim; ++i)
649 sumConstr += F_fac_vec[i]*fabs(F_vec[i]);
651 if ( std::isnan(sumConstr) ) {
return nullptr; }
652 if (sumConstr < 0.001) { onConstr =
true; }
655 for (
unsigned int i=0; i<nTrk; ++i)
657 Bjac_mat(i,0+5*i) = dFxydd0(i);
658 Bjac_mat(i,1+5*i) = dFxydz0(i);
659 Bjac_mat(i,2+5*i) = dFxydphi(i);
660 Bjac_mat(i,3+5*i) = dFxydtheta(i);
661 Bjac_mat(i,4+5*i) = dFxydqOverP(i);
662 Bjac_mat(i+nTrk,0+5*i) = dFxzdd0(i);
663 Bjac_mat(i+nTrk,1+5*i) = dFxzdz0(i);
664 Bjac_mat(i+nTrk,2+5*i) = dFxzdphi(i);
665 Bjac_mat(i+nTrk,3+5*i) = dFxzdtheta(i);
666 Bjac_mat(i+nTrk,4+5*i) = dFxzdqOverP(i);
668 Bjac_mat(2*nTrk,0+5*i) = dFMassdd0(i);
669 Bjac_mat(2*nTrk,1+5*i) = dFMassdz0(i);
670 Bjac_mat(2*nTrk,2+5*i) = dFMassdphi(i);
671 Bjac_mat(2*nTrk,3+5*i) = dFMassdtheta(i);
672 Bjac_mat(2*nTrk,4+5*i) = dFMassdqOverP(i);
674 if(pointingConstraint) {
676 Bjac_mat(2*nTrk+1,0+5*i) = dFPxydd0(i);
677 Bjac_mat(2*nTrk+1,1+5*i) = dFPxydz0(i);
678 Bjac_mat(2*nTrk+1,2+5*i) = dFPxydphi(i);
679 Bjac_mat(2*nTrk+1,3+5*i) = dFPxydtheta(i);
680 Bjac_mat(2*nTrk+1,4+5*i) = dFPxydqOverP(i);
681 Bjac_mat(2*nTrk+1,5*nTrk) = dFPxydxp;
682 Bjac_mat(2*nTrk+1,5*nTrk+1) = dFPxydyp;
683 Bjac_mat(2*nTrk+1,5*nTrk+2) = dFPxydzp;
684 Bjac_mat(2*nTrk+2,0+5*i) = dFPxzdd0(i);
685 Bjac_mat(2*nTrk+2,1+5*i) = dFPxzdz0(i);
686 Bjac_mat(2*nTrk+2,2+5*i) = dFPxzdphi(i);
687 Bjac_mat(2*nTrk+2,3+5*i) = dFPxzdtheta(i);
688 Bjac_mat(2*nTrk+2,4+5*i) = dFPxzdqOverP(i);
689 Bjac_mat(2*nTrk+2,5*nTrk) = dFPxzdxp;
690 Bjac_mat(2*nTrk+2,5*nTrk+1) = dFPxzdyp;
691 Bjac_mat(2*nTrk+2,5*nTrk+2) = dFPxzdzp;
693 Bjac_mat(2*nTrk+0,0+5*i) = dFPxydd0(i);
694 Bjac_mat(2*nTrk+0,1+5*i) = dFPxydz0(i);
695 Bjac_mat(2*nTrk+0,2+5*i) = dFPxydphi(i);
696 Bjac_mat(2*nTrk+0,3+5*i) = dFPxydtheta(i);
697 Bjac_mat(2*nTrk+0,4+5*i) = dFPxydqOverP(i);
698 Bjac_mat(2*nTrk+0,5*nTrk) = dFPxydxp;
699 Bjac_mat(2*nTrk+0,5*nTrk+1) = dFPxydyp;
700 Bjac_mat(2*nTrk+0,5*nTrk+2) = dFPxydzp;
701 Bjac_mat(2*nTrk+1,0+5*i) = dFPxzdd0(i);
702 Bjac_mat(2*nTrk+1,1+5*i) = dFPxzdz0(i);
703 Bjac_mat(2*nTrk+1,2+5*i) = dFPxzdphi(i);
704 Bjac_mat(2*nTrk+1,3+5*i) = dFPxzdtheta(i);
705 Bjac_mat(2*nTrk+1,4+5*i) = dFPxzdqOverP(i);
706 Bjac_mat(2*nTrk+1,5*nTrk) = dFPxzdxp;
707 Bjac_mat(2*nTrk+1,5*nTrk+1) = dFPxzdyp;
708 Bjac_mat(2*nTrk+1,5*nTrk+2) = dFPxzdzp;
712 Ajac_mat(i,0) = dFxydxs(i);
713 Ajac_mat(i,1) = dFxydys(i);
714 Ajac_mat(i,2) = dFxydzs(i);
715 Ajac_mat(i+nTrk,0) = dFxzdxs(i);
716 Ajac_mat(i+nTrk,1) = dFxzdys(i);
717 Ajac_mat(i+nTrk,2) = dFxzdzs(i);
719 Ajac_mat(2*nTrk,0) = dFMassdxs;
720 Ajac_mat(2*nTrk,1) = dFMassdys;
721 Ajac_mat(2*nTrk,2) = dFMassdzs;
723 if(pointingConstraint) {
725 Ajac_mat(2*nTrk+1,0) = dFPxydxs;
726 Ajac_mat(2*nTrk+1,1) = dFPxydys;
727 Ajac_mat(2*nTrk+1,2) = dFPxydzs;
728 Ajac_mat(2*nTrk+2,0) = dFPxzdxs;
729 Ajac_mat(2*nTrk+2,1) = dFPxzdys;
730 Ajac_mat(2*nTrk+2,2) = dFPxzdzs;
732 Ajac_mat(2*nTrk+0,0) = dFPxydxs;
733 Ajac_mat(2*nTrk+0,1) = dFPxydys;
734 Ajac_mat(2*nTrk+0,2) = dFPxydzs;
735 Ajac_mat(2*nTrk+1,0) = dFPxzdxs;
736 Ajac_mat(2*nTrk+1,1) = dFPxzdys;
737 Ajac_mat(2*nTrk+1,2) = dFPxzdzs;
742 Wb_mat = Wmeas_mat.similarity(Bjac_mat) ;
743 Wb_mat = Wb_mat.inverse();
745 C22_mat = Wb_mat.similarity(Ajac_mat.transpose());
746 C22_mat = C22_mat.inverse();
748 Btemp_mat = Wb_mat * Bjac_mat * Wmeas_mat;
749 Atemp_mat = Wb_mat * Ajac_mat;
751 C21_mat = - C22_mat * Ajac_mat.transpose() * Btemp_mat;
752 C32_mat = Atemp_mat * C22_mat;
753 C31_mat = Btemp_mat + Atemp_mat * C21_mat;
754 Amg::MatrixX mat_prod_1 = Wmeas_mat * Bjac_mat.transpose();
755 Amg::MatrixX mat_prod_2 = Wmeas_mat * Bjac_mat.transpose() * Wb_mat * Ajac_mat;
756 C11_mat = Wmeas_mat - Wb_mat.similarity( mat_prod_1 ) + C22_mat.similarity( mat_prod_2 );
758 C_cor_vec = Ajac_mat*DeltaA_vec + Bjac_mat*DeltaY_vec;
759 C_vec = C_cor_vec + F_vec;
761 DeltaY_vec = C31_mat.transpose()*C_vec;
762 DeltaA_vec = C32_mat.transpose()*C_vec;
764 for (
unsigned int i=0; i<n_dim; ++i)
766 ChiItr_vec(0,i) = DeltaY_vec(i);
768 ChiItr_mat = Wmeas0_mat.similarity( ChiItr_vec );
769 chi2New = ChiItr_mat(0,0);
772 frameOriginItr[0] += DeltaA_vec(0);
773 frameOriginItr[1] += DeltaA_vec(1);
774 frameOriginItr[2] += DeltaA_vec(2);
775 if (msgLvl(MSG::DEBUG)) {
776 msg(MSG::DEBUG) <<
"New vertex, global coordinates: " << frameOriginItr.transpose() <<
endmsg;
777 msg(MSG::DEBUG) <<
"chi2Old: " << chi2Old <<
" chi2New: " << chi2New <<
" fabs(chi2Old-chi2New): " << fabs(chi2Old-chi2New) <<
endmsg;
781 if (globalPositionItr->perp() >
m_maxR && globalPositionItr->z() >
m_maxZ)
return nullptr;
783 if (onConstr && fabs(chi2Old-chi2New) < 0.1) {
break; }
786 fieldCache.
getField(globalPositionItr->data(),BFieldItr);
787 double B_z_new = BFieldItr[2]*299.792;
788 if (B_z_new == 0. || std::isnan(B_z_new)) {
794 double deltaR = sqrt(DeltaA_vec(0)*DeltaA_vec(0)+DeltaA_vec(1)*DeltaA_vec(1)+DeltaA_vec(2)*DeltaA_vec(2));
795 double deltaB_z = fabs(B_z-B_z_new)/B_z;
796 bool changeBz =
false;
807 v0FitterTracks.clear();
812 if (chargeParameters !=
nullptr)
815 const Amg::Vector3D gMomentum = chargeParameters->momentum();
816 const Amg::Vector3D gDirection = chargeParameters->position() - *globalPositionItr;
817 const double extrapolationDirection = gMomentum .dot( gDirection );
820 std::unique_ptr<const Trk::Perigee> extrapolatedPerigee(
nullptr);
822 std::unique_ptr<const Trk::TrackParameters> tmp =
823 std::abs(chargeParameters->position().z()) >
m_maxZ ? nullptr :
834 extrapolatedPerigee.reset(
838 if (extrapolatedPerigee ==
nullptr) {
839 ATH_MSG_DEBUG(
"Perigee was not extrapolated! Taking original one!");
841 if (tmpPerigee!=
nullptr) extrapolatedPerigee = std::make_unique<Trk::Perigee>(*tmpPerigee);
846 V0FitterTrack locV0FitterTrack;
847 locV0FitterTrack.TrkPar[0] = extrapolatedPerigee->parameters()[
Trk::d0];
848 locV0FitterTrack.TrkPar[1] = extrapolatedPerigee->parameters()[
Trk::z0];
849 locV0FitterTrack.TrkPar[2] = extrapolatedPerigee->parameters()[
Trk::phi];
850 locV0FitterTrack.TrkPar[3] = extrapolatedPerigee->parameters()[
Trk::theta];
851 locV0FitterTrack.TrkPar[4] = extrapolatedPerigee->parameters()[
Trk::qOverP];
852 locV0FitterTrack.Wi_mat = extrapolatedPerigee->covariance()->inverse().eval();
853 locV0FitterTrack.originalPerigee = chargeParameters;
854 v0FitterTracks.push_back(locV0FitterTrack);
856 ATH_MSG_DEBUG(
"Track parameters are not charged tracks ... fit aborted");
860 frameOrigin = frameOriginItr;
866 chi2Old = 2000000000000.;
877 frameOrigin[0] += DeltaA_vec(0);
878 frameOrigin[1] += DeltaA_vec(1);
879 frameOrigin[2] += DeltaA_vec(2);
880 if ( std::isnan(frameOrigin[0]) || std::isnan(frameOrigin[1]) || std::isnan(frameOrigin[2]) )
return nullptr;
882 Y_vec = Y0_vec + DeltaY_vec;
885 for (
unsigned int i=0; i<nTrk; ++i)
887 if ( fabs ( Y_vec(2+5*i) ) > 100. || fabs ( Y_vec(3+5*i) ) > 100. ) {
return nullptr; }
888 while ( fabs ( Y_vec(2+5*i) ) >
M_PI ) Y_vec(2+5*i) += ( Y_vec(2+5*i) > 0 ) ? -2*
M_PI : 2*
M_PI;
889 while ( Y_vec(3+5*i) > 2*
M_PI ) Y_vec(3+5*i) -= 2*
M_PI;
890 while ( Y_vec(3+5*i) < -
M_PI ) Y_vec(3+5*i) +=
M_PI;
891 if ( Y_vec(3+5*i) >
M_PI )
893 Y_vec(3+5*i) = 2*
M_PI - Y_vec(3+5*i);
894 if ( Y_vec(2+5*i) >= 0 ) Y_vec(2+5*i) += ( Y_vec(2+5*i) >0 ) ? -
M_PI :
M_PI;
896 if ( Y_vec(3+5*i) < 0.0 )
898 Y_vec(3+5*i) = - Y_vec(3+5*i);
899 if ( Y_vec(2+5*i) >= 0 ) Y_vec(2+5*i) += ( Y_vec(2+5*i) >0 ) ? -
M_PI :
M_PI;
903 for (
unsigned int i=0; i<n_dim; ++i)
905 Chi_vec(0,i) = DeltaY_vec(i);
907 Chi_mat = Wmeas0_mat.similarity( Chi_vec );
911 V_mat.block(0,0,n_dim,n_dim) = C11_mat;
912 V_mat.block<3,3>(n_dim,n_dim) = C22_mat;
913 V_mat.block(n_dim,0,3,n_dim) = C21_mat;
914 V_mat.block(0,n_dim,n_dim,3) = C21_mat.transpose();
917 std::vector<V0FitterTrack>::iterator BTIter;
919 for (BTIter = v0FitterTracks.begin(); BTIter != v0FitterTracks.end() ; ++BTIter)
922 AmgSymMatrix(5) covTrk = Wmeas0_mat.block<5,5>(5*iRP,5*iRP);
924 for (
unsigned int i=0; i<5; ++i) chi_vec(i) = DeltaY_vec(i+5*iRP);
925 double chi2Trk = chi_vec.dot(covTrk*chi_vec);
926 (*BTIter).chi2=chi2Trk;
931 auto vx = std::make_unique<xAOD::Vertex>();
932 vx->makePrivateStore();
933 vx->setPosition (frameOrigin);
934 vx->setCovariancePosition (C22_mat);
935 vx->setFitQuality(
chi2,
static_cast<float>(ndf));
939 std::vector<VxTrackAtVertex> & tracksAtVertex = vx->vxTrackAtVertex(); tracksAtVertex.clear();
943 unsigned int iterf=0;
944 std::vector<V0FitterTrack>::iterator BTIterf;
945 for (BTIterf = v0FitterTracks.begin(); BTIterf != v0FitterTracks.end() ; ++BTIterf)
947 AmgSymMatrix(5) CovMtxP = V_mat.block<5,5>(5*iterf, 5*iterf);
948 refittedPerigee =
new Trk::Perigee (Y_vec(0+5*iterf),Y_vec(1+5*iterf),Y_vec(2+5*iterf),Y_vec(3+5*iterf),Y_vec(4+5*iterf),
950 tracksAtVertex.emplace_back((*BTIterf).chi2, refittedPerigee, (*BTIterf).originalPerigee);
955 unsigned int sfcmv = nPar*(nPar+1)/2;
956 std::vector<float> floatErrMtx(sfcmv,0.);
957 unsigned int ipnt = 0;
958 for (
unsigned int i=0; i<nPar; ++i) {
959 for (
unsigned int j=0; j<i+1; ++j) {
960 floatErrMtx[ipnt++]=V_mat(i,j);
963 vx->setCovariance(floatErrMtx);