19#include "CLHEP/GenericFunctions/CumulativeChiSquare.hh"
22#include "CLHEP/Vector/LorentzVector.h"
29 declareInterface<V0Tools>(
this);
37 return StatusCode::SUCCESS;
42 std::array<double, 2> masses = {posTrackMass, negTrackMass};
51 double px = 0.,
py = 0.,
pz = 0., e = 0.;
53 if (masses.size() != NTrk) {
54 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
57 for(
unsigned int it=0; it<NTrk; it++) {
58 if (masses[it] >= 0.) {
60 px += lorentz_trk.Px();
61 py += lorentz_trk.Py();
62 pz += lorentz_trk.Pz();
67 return (msq>0.) ? sqrt(msq) : 0.;
72 std::array<double, 2> masses = {posTrackMass, negTrackMass};
80 if (masses.size() != NTrk) {
81 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
84 double error = -999999.;
86 if (fullCov.size() == 0) {
87 ATH_MSG_DEBUG(
"0 pointer for full covariance. Making-up one from the vertex and tracks covariances");
90 unsigned int ndim = fullCov.rows();
92 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
94 }
else if (ndim == 3*NTrk+3) {
104 std::array<double, 2> masses = {posTrackMass, negTrackMass};
112 if (masses.size() != NTrk) {
113 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
117 if (fullCov.size() == 0)
return -999999.;
118 unsigned int ndim = fullCov.rows();
119 double E=0., Px=0., Py=0., Pz=0.;
121 std::vector<double>dm2dphi(NTrk), dm2dtheta(NTrk), dm2dqOverP(NTrk);
122 for(
unsigned int it=0; it<NTrk; it++) {
123 if (masses[it] >= 0.) {
125 double trkCharge = 1.;
126 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
131 double tmp = 1./(
qOverP[it]*
qOverP[it]) + masses[it]*masses[it];
132 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
140 double msq = E*E - Px*Px - Py*Py - Pz*Pz;
141 double mass = (msq>0.) ? sqrt(msq) : 0.;
143 for(
unsigned int it=0; it<NTrk; it++) {
144 if (masses[it] >= 0.) {
152 for(
unsigned int it=0; it<NTrk; it++) {
153 D_vec(5*it+0,0) = 0.;
154 D_vec(5*it+1,0) = 0.;
155 D_vec(5*it+2,0) = dm2dphi[it];
156 D_vec(5*it+3,0) = dm2dtheta[it];
157 D_vec(5*it+4,0) = dm2dqOverP[it];
159 Amg::MatrixX V0_merr = D_vec.transpose() * fullCov.block(0,0,ndim-3,ndim-3) * D_vec;
161 double massVarsq = V0_merr(0,0);
162 if (massVarsq <= 0.)
ATH_MSG_DEBUG(
"massError: negative sqrt massVarsq " << massVarsq);
163 double massVar = (massVarsq>0.) ? sqrt(massVarsq) : 0.;
164 double massErr = massVar/(2.*mass);
170 std::array<double, 2> masses = {posTrackMass, negTrackMass};
177 if (masses.size() != NTrk) {
178 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
181 std::vector<xAOD::TrackParticle::FourMom_t> particleMom(NTrk);
182 std::vector<
AmgMatrix(3,3)> particleDeriv(NTrk);
184 AmgMatrix(3,3) tmpDeriv; tmpDeriv.setZero();
186 if (fullCov.size() == 0)
return -999999.;
188 for(
unsigned int it=0; it<NTrk; it++){
189 if (masses[it] >= 0.) {
196 double pz = cos(
theta)/fabs(invP);
197 double esq =
px*
px +
py*
py +
pz*
pz + masses[it]*masses[it];
198 double e = (esq>0.) ? sqrt(esq) : 0.;
200 tmp.SetPxPyPzE(
px,
py,
pz,e);
201 particleMom[it] = tmp;
205 tmpDeriv(0,0) = - tmp.Py();
206 tmpDeriv(1,0) = tmp.Px();
208 tmpDeriv(0,1) = cos(
phi) * tmp.Pz();
209 tmpDeriv(1,1) = sin(
phi) * tmp.Pz();
210 tmpDeriv(2,1) = - sin(
theta)/fabs(invP);
211 tmpDeriv(0,2) = - tmp.Px()/invP;
212 tmpDeriv(1,2) = - tmp.Py()/invP;
213 tmpDeriv(2,2) = - tmp.Pz()/invP;
214 particleDeriv[it] = tmpDeriv;
218 std::vector<double> Deriv(3*NTrk+3, 0.);
219 for(
unsigned int it=0; it<NTrk; it++){
220 if (masses[it] >= 0.) {
221 double dMdPx = ( totalMom.E() * particleMom[it].Px()/particleMom[it].E() - totalMom.Px() ) / totalMom.M();
222 double dMdPy = ( totalMom.E() * particleMom[it].Py()/particleMom[it].E() - totalMom.Py() ) / totalMom.M();
223 double dMdPz = ( totalMom.E() * particleMom[it].Pz()/particleMom[it].E() - totalMom.Pz() ) / totalMom.M();
225 double dMdPhi = dMdPx*particleDeriv[it](0,0) + dMdPy*particleDeriv[it](1,0) + dMdPz*particleDeriv[it](2,0);
226 double dMdTheta = dMdPx*particleDeriv[it](0,1) + dMdPy*particleDeriv[it](1,1) + dMdPz*particleDeriv[it](2,1);
227 double dMdInvP = dMdPx*particleDeriv[it](0,2) + dMdPy*particleDeriv[it](1,2) + dMdPz*particleDeriv[it](2,2);
229 Deriv[3*it + 3 + 0] = dMdPhi; Deriv[3*it + 3 + 1] = dMdTheta; Deriv[3*it + 3 + 2] = dMdInvP;
234 for(
unsigned int i=0; i<3*NTrk+3; i++){
235 for(
unsigned int j=0; j<3*NTrk+3; j++){
236 err += Deriv[i]*( fullCov)(i,j)*Deriv[j];
239 if (err <= 0.)
ATH_MSG_DEBUG(
"massError: negative sqrt err " << err);
240 return (err>0.) ? sqrt(err) : 0.;
245 std::array<double, 2> masses = {posTrackMass, negTrackMass};
253 if (masses.size() != NTrk) {
254 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
257 double E=0., Px=0., Py=0., Pz=0.;
259 std::vector<double>dm2dphi(NTrk), dm2dtheta(NTrk), dm2dqOverP(NTrk);
261 for(
unsigned int it=0; it<NTrk; it++) {
262 if (masses[it] >= 0.) {
265 V0_cor(5*it+2,5*it+2) = (*cov_tmp)(2,2);
266 V0_cor(5*it+2,5*it+3) = (*cov_tmp)(2,3);
267 V0_cor(5*it+2,5*it+4) = (*cov_tmp)(2,4);
268 V0_cor(5*it+3,5*it+3) = (*cov_tmp)(3,3);
269 V0_cor(5*it+3,5*it+4) = (*cov_tmp)(3,4);
270 V0_cor(5*it+4,5*it+4) = (*cov_tmp)(4,4);
271 V0_cor(5*it+3,5*it+2) = (*cov_tmp)(2,3);
272 V0_cor(5*it+4,5*it+2) = (*cov_tmp)(2,4);
273 V0_cor(5*it+4,5*it+3) = (*cov_tmp)(3,4);
274 double trkCharge = 1.;
275 if (bPer->parameters()(
Trk::qOverP) < 0.) trkCharge = -1.;
280 double tmp = 1./(
qOverP[it]*
qOverP[it]) + masses[it]*masses[it];
281 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
289 double msq = E*E - Px*Px - Py*Py - Pz*Pz;
290 double mass = (msq>0.) ? sqrt(msq) : 0.;
292 for(
unsigned int it=0; it<NTrk; it++) {
293 if (masses[it] >= 0.) {
301 for(
unsigned int it=0; it<NTrk; it++) {
302 D_vec(5*it+0,0) = 0.;
303 D_vec(5*it+1,0) = 0.;
304 D_vec(5*it+2,0) = dm2dphi[it];
305 D_vec(5*it+3,0) = dm2dtheta[it];
306 D_vec(5*it+4,0) = dm2dqOverP[it];
309 Amg::MatrixX V0_merr = D_vec.transpose() * V0_cor * D_vec;
311 double massVarsq = V0_merr(0,0);
312 if (massVarsq <= 0.)
ATH_MSG_DEBUG(
"massError: negative sqrt massVarsq " << massVarsq);
313 double massVar = (massVarsq>0.) ? sqrt(massVarsq) : 0.;
314 double massErr = massVar/(2.*mass);
320 std::array<double, 2> masses = {posTrackMass , negTrackMass};
331 double chi2 = (V0Mass - mass)*(V0Mass - mass)/(massErr*massErr);
333 Genfun::CumulativeChiSquare myCumulativeChiSquare(ndf);
335 double achi2prob = 1.-myCumulativeChiSquare(
chi2);
351 double chi2 = (V0Mass - mass)*(V0Mass - mass)/(massErr*massErr);
353 Genfun::CumulativeChiSquare myCumulativeChiSquare(ndf);
355 double achi2prob = 1.-myCumulativeChiSquare(
chi2);
377 if (NTrk != 2)
return mom;
378 for(
unsigned int it=0; it<NTrk; it++) {
389 if (NTrk != 2)
return mom;
390 for(
unsigned int it=0; it<NTrk; it++) {
401 for(
unsigned int it=0; it<NTrk; it++) {
411 double tmp = mass*mass + mom.x()*mom.x() + mom.y()*mom.y() + mom.z()*mom.z();
412 double e = (tmp>0.) ? sqrt(tmp) : 0.;
413 lorentz.SetPxPyPzE(mom.x(), mom.y(), mom.z(), e);
421 double tmp = mass*mass + mom.x()*mom.x() + mom.y()*mom.y() + mom.z()*mom.z();
422 double e = (tmp>0.) ? sqrt(tmp) : 0.;
423 lorentz.SetPxPyPzE(mom.x(), mom.y(), mom.z(), e);
431 double tmp = mass*mass + mom.x()*mom.x() + mom.y()*mom.y() + mom.z()*mom.z();
432 double e = (tmp>0.) ? sqrt(tmp) : 0.;
433 lorentz.SetPxPyPzE(mom.x(), mom.y(), mom.z(), e);
440 double tmp = V0Mass*V0Mass + mom.x()*mom.x() + mom.y()*mom.y() + mom.z()*mom.z();
441 double e = (tmp>0.) ? sqrt(tmp) : 0.;
443 lorentz.SetPxPyPzE(mom.x(), mom.y(), mom.z(), e);
459 float dof =
ndof(vxCandidate);
461 Genfun::CumulativeChiSquare myCumulativeChiSquare(dof);
462 float chi =
chisq(vxCandidate);
464 double chi2prob = 1.-myCumulativeChiSquare(chi);
484 return vxCandidate->
position().perp();
499 double rxysq = dx*dx + dy*dy;
500 double rxy = (rxysq>0.) ? sqrt(rxysq) : 0.;
501 double drdx = dx/
rxy;
502 double drdy = dy/
rxy;
506 Amg::MatrixX rxy_err = D_vec.transpose() * cov.block(0,0,2,2) * D_vec;
507 double rxyVar = rxy_err(0,0);
513 const Amg::MatrixX& cov = vxCandidate->covariancePosition();
514 double dx = vxCandidate->
position().x();
515 double dy = vxCandidate->
position().y();
516 double rxyVar =
rxy_var(dx,dy,cov);
517 if (rxyVar <= 0.)
ATH_MSG_DEBUG(
"rxyError: negative sqrt rxyVar " << rxyVar);
518 return (rxyVar>0.) ? sqrt(rxyVar) : 0.;
523 const Amg::MatrixX cov = vxCandidate->covariancePosition() +
vertex->covariancePosition();
525 double dx = vert.x();
526 double dy = vert.y();
527 double rxyVar =
rxy_var(dx,dy,cov);
528 if (rxyVar <= 0.)
ATH_MSG_DEBUG(
"rxyError: negative sqrt rxyVar " << rxyVar);
529 return (rxyVar>0.) ? sqrt(rxyVar) : 0.;
534 const Amg::MatrixX& cov = vxCandidate->covariancePosition();
536 double dx = vert.x();
537 double dy = vert.y();
538 double rxyVar =
rxy_var(dx,dy,cov);
539 if (rxyVar <= 0.)
ATH_MSG_DEBUG(
"rxyError: negative sqrt rxyVar " << rxyVar);
540 return (rxyVar>0.) ? sqrt(rxyVar) : 0.;
552 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
553 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
554 std::vector<double>dPTdqOverP(NTrk), dPTdtheta(NTrk), dPTdphi(NTrk);
557 for(
unsigned int it=0; it<NTrk; it++) {
559 double trkCharge = 1.;
560 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
573 double PTsq = Px*Px+Py*Py;
574 double PT = (PTsq>0.) ? sqrt(PTsq) : 0.;
576 for(
unsigned int it=0; it<NTrk; it++) {
577 dPTdqOverP[it] = (Px*dpxdqOverP[it]+Py*dpydqOverP[it])/PT;
578 dPTdtheta[it] = (Px*dpxdtheta[it]+Py*dpydtheta[it])/PT;
579 dPTdphi[it] = (Px*dpxdphi[it]+Py*dpydphi[it])/PT;
582 unsigned int ndim = 0;
583 if (fullCov.size() == 0) {
586 ndim = fullCov.rows();
590 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
592 for(
unsigned int it=0; it<NTrk; it++) {
593 D_vec(5*it+0,0) = 0.;
594 D_vec(5*it+1,0) = 0.;
595 D_vec(5*it+2,0) = dPTdphi[it];
596 D_vec(5*it+3,0) = dPTdtheta[it];
597 D_vec(5*it+4,0) = dPTdqOverP[it];
599 if (fullCov.size() == 0) {
601 PtErrSq = D_vec.transpose() * V0_cov * D_vec;
603 PtErrSq = D_vec.transpose() * fullCov.block(0,0,5*NTrk-1,5*NTrk-1) * D_vec;
605 }
else if (ndim == 3*NTrk+3) {
607 for(
unsigned int it=0; it<NTrk; it++) {
608 D_vec(3*it+0,0) = dPTdphi[it];
609 D_vec(3*it+1,0) = dPTdtheta[it];
610 D_vec(3*it+2,0) = dPTdqOverP[it];
612 PtErrSq = D_vec.transpose() * fullCov.block(3,3,ndim-3,ndim-3) * D_vec;
615 double PtErrsq = PtErrSq(0,0);
616 if (PtErrsq <= 0.)
ATH_MSG_DEBUG(
"ptError: negative sqrt PtErrsq " << PtErrsq);
617 return (PtErrsq>0.) ? sqrt(PtErrsq) : 0.;
622 assert(vxCandidate!=0);
623 if(
nullptr == vxCandidate) {
630 double p2 =
P.mag2();
631 double pdr =
P.dot((sv - pv));
632 return sv -
P*pdr/p2;
637 const Amg::MatrixX& cov = (vxCandidate->covariancePosition() +
vertex->covariancePosition()).inverse().eval();
643 Amg::MatrixX sepVarsqMat = D_vec.transpose() * cov * D_vec;
644 double sepVarsq = sepVarsqMat(0,0);
645 if (sepVarsq <= 0.)
ATH_MSG_DEBUG(
"separation: negative sqrt sepVarsq " << sepVarsq);
646 double sepVar = (sepVarsq>0.) ? sqrt(sepVarsq) : 0.;
652 const Amg::SymMatrixX& cov = vxCandidate->covariancePosition().inverse().eval();
658 Amg::MatrixX sepVarsqMat = D_vec.transpose() * cov * D_vec;
659 double sepVarsq = sepVarsqMat(0,0);
660 if (sepVarsq <= 0.)
ATH_MSG_DEBUG(
"separation: negative sqrt sepVarsq " << sepVarsq);
661 double sepVar = (sepVarsq>0.) ? sqrt(sepVarsq) : 0.;
668 double sinTheta_xy = ((1.-cosineTheta_xy*cosineTheta_xy)>0.) ? sqrt((1.-cosineTheta_xy*cosineTheta_xy)) : 0.;
669 return (
vtx(vxCandidate)-
vertex->position()).perp() * sinTheta_xy;
684 double sinTheta = ((1.-cosineTheta*cosineTheta)>0.) ? sqrt((1.-cosineTheta*cosineTheta)) : 0.;
685 return (
vtx(vxCandidate)-
vertex->position()).mag() * sinTheta;
693 double dx = vert.x();
694 double dy = vert.y();
695 double dz = vert.z();
696 double Px=0., Py=0., Pz=0.;
697 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
698 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
699 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk);
700 std::vector<double>da0dqOverP(NTrk), da0dtheta(NTrk), da0dphi(NTrk);
703 for(
unsigned int it=0; it<NTrk; it++) {
705 double trkCharge = 1.;
706 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
722 double P2 = Px*Px+Py*Py+Pz*Pz;
723 double B = Px*dx+Py*dy+Pz*dz;
725 double da0dx = (Px*Pz)/P2;
726 double da0dy = (Py*Pz)/P2;
727 double da0dz = (Pz*Pz)/P2 - 1.;
728 double da0dx0 = -da0dx;
729 double da0dy0 = -da0dy;
730 double da0dz0 = -da0dz;
731 for(
unsigned int it=0; it<NTrk; it++) {
732 double dP2dqOverP = 2.*(Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it]);
733 double dP2dtheta = 2.*(Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it]);
734 double dP2dphi = 2.*(Px*dpxdphi[it]+Py*dpydphi[it]);
735 da0dqOverP[it] = (B*(P2*dpzdqOverP[it]-Pz*dP2dqOverP) +
736 Pz*P2*(dx*dpxdqOverP[it]+dy*dpydqOverP[it]+dz*dpzdqOverP[it]))/(P2*P2);
737 da0dtheta[it] = (B*(P2*dpzdtheta[it]-Pz*dP2dtheta) +
738 Pz*P2*(dx*dpxdtheta[it]+dy*dpydtheta[it]+dz*dpzdtheta[it]))/(P2*P2);
739 da0dphi[it] = -(B*Pz*dP2dphi -
740 Pz*P2*(dx*dpxdphi[it]+dy*dpydphi[it]))/(P2*P2);
743 unsigned int ndim = 0;
744 if (fullCov.size() != 0) {
745 ndim = fullCov.rows();
751 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
753 for(
unsigned int it=0; it<NTrk; it++) {
756 D_vec(5*it+2) = da0dphi[it];
757 D_vec(5*it+3) = da0dtheta[it];
758 D_vec(5*it+4) = da0dqOverP[it];
760 D_vec(5*NTrk+0) = da0dx;
761 D_vec(5*NTrk+1) = da0dy;
762 D_vec(5*NTrk+2) = da0dz;
763 D_vec(5*NTrk+3) = da0dx0;
764 D_vec(5*NTrk+4) = da0dy0;
765 D_vec(5*NTrk+5) = da0dz0;
768 if (fullCov.size() != 0) {
769 W_mat.block(0,0,ndim,ndim) = fullCov;
772 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
773 W_mat.block(5*NTrk,5*NTrk,3,3) = vxCandidate->covariancePosition();
775 W_mat.block(5*NTrk+3,5*NTrk+3,3,3) =
vertex->covariancePosition();
776 V0_err = D_vec.transpose() * W_mat * D_vec;
777 }
else if (ndim == 3*NTrk+3) {
782 for(
unsigned int it=0; it<NTrk; it++) {
783 D_vec(3*it+3) = da0dphi[it];
784 D_vec(3*it+4) = da0dtheta[it];
785 D_vec(3*it+5) = da0dqOverP[it];
787 D_vec(3*NTrk+3) = da0dx0;
788 D_vec(3*NTrk+4) = da0dy0;
789 D_vec(3*NTrk+5) = da0dz0;
792 W_mat.block(0,0,ndim,ndim) = fullCov;
793 W_mat.block(3*NTrk+3,3*NTrk+3,3,3) =
vertex->covariancePosition();
794 V0_err = D_vec.transpose() * W_mat * D_vec;
797 double a0Errsq = V0_err(0,0);
798 if (a0Errsq <= 0.)
ATH_MSG_DEBUG(
"a0Error: negative sqrt a0Errsq " << a0Errsq);
799 double a0Err = (a0Errsq>0.) ? sqrt(a0Errsq) : 0.;
812 double dx = vert.x();
813 double dy = vert.y();
814 double dz = vert.z();
815 double Px=0., Py=0., Pz=0.;
816 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
817 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
818 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk);
819 std::vector<double>da0dqOverP(NTrk), da0dtheta(NTrk), da0dphi(NTrk);
822 for(
unsigned int it=0; it<NTrk; it++) {
824 double trkCharge = 1.;
825 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
854 double P = sqrt(Px*Px+Py*Py+Pz*Pz);
855 double r = sqrt(dx*dx+dy*dy+dz*dz);
857 double da0dx = (Px/
P*
r*cosineTheta - dx)/a0val;
858 double da0dy = (Py/
P*
r*cosineTheta - dy)/a0val;
859 double da0dz = (Pz/
P*
r*cosineTheta - dz)/a0val;
860 double da0dx0 = -da0dx;
861 double da0dy0 = -da0dy;
862 double da0dz0 = -da0dz;
863 for(
unsigned int it=0; it<NTrk; it++) {
864 da0dqOverP[it] = -(
r*cosineTheta/
P)*(da0dx*dpxdqOverP[it]+da0dy*dpydqOverP[it]+da0dz*dpzdqOverP[it]);
865 da0dtheta[it] = -(
r*cosineTheta/
P)*(da0dx*dpxdtheta[it]+da0dy*dpydtheta[it]+da0dz*dpzdtheta[it]);
866 da0dphi[it] = -(
r*cosineTheta/
P)*(da0dx*dpxdphi[it]+da0dy*dpydphi[it]);
869 unsigned int ndim = 0;
870 if (fullCov.size() != 0) {
871 ndim = fullCov.rows();
877 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
879 for(
unsigned int it=0; it<NTrk; it++) {
882 D_vec(5*it+2) = da0dphi[it];
883 D_vec(5*it+3) = da0dtheta[it];
884 D_vec(5*it+4) = da0dqOverP[it];
886 D_vec(5*NTrk+0) = da0dx;
887 D_vec(5*NTrk+1) = da0dy;
888 D_vec(5*NTrk+2) = da0dz;
889 D_vec(5*NTrk+3) = da0dx0;
890 D_vec(5*NTrk+4) = da0dy0;
891 D_vec(5*NTrk+5) = da0dz0;
894 if (fullCov.size() != 0) {
895 W_mat.block(0,0,ndim,ndim) = fullCov;
898 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
899 W_mat.block(5*NTrk,5*NTrk,3,3) = vxCandidate->covariancePosition();
901 W_mat.block(5*NTrk+3,5*NTrk+3,3,3) =
vertex->covariancePosition();
902 V0_err = D_vec.transpose() * W_mat * D_vec;
903 }
else if (ndim == 3*NTrk+3) {
908 for(
unsigned int it=0; it<NTrk; it++) {
909 D_vec(3*it+3) = da0dphi[it];
910 D_vec(3*it+4) = da0dtheta[it];
911 D_vec(3*it+5) = da0dqOverP[it];
913 D_vec(3*NTrk+3) = da0dx0;
914 D_vec(3*NTrk+4) = da0dy0;
915 D_vec(3*NTrk+5) = da0dz0;
918 W_mat.block(0,0,ndim,ndim) = fullCov;
919 W_mat.block(3*NTrk+3,3*NTrk+3,3,3) =
vertex->covariancePosition();
920 V0_err = D_vec.transpose() * W_mat * D_vec;
923 double a0Errsq = V0_err(0,0);
924 if (a0Errsq <= 0.)
ATH_MSG_DEBUG(
"a0Error: negative sqrt a0Errsq " << a0Errsq);
925 double a0Err = (a0Errsq>0.) ? sqrt(a0Errsq) : 0.;
932 double dx = vert.x();
933 double dy = vert.y();
935 double dxy = (mom.x()*dx + mom.y()*dy)/mom.perp();
942 double dx = vert.x();
943 double dy = vert.y();
946 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
947 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
948 std::vector<double>dLxydqOverP(NTrk), dLxydtheta(NTrk), dLxydphi(NTrk);
951 for(
unsigned int it=0; it<NTrk; it++) {
953 double trkCharge = 1.;
954 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
967 double PTsq = Px*Px+Py*Py;
968 double PT = (PTsq>0.) ? sqrt(PTsq) : 0.;
969 double LXYoverPT = (Px*dx+Py*dy)/PTsq;
971 for(
unsigned int it=0; it<NTrk; it++) {
972 double dPTdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it])/PT;
973 double dPTdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it])/PT;
974 double dPTdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/PT;
975 dLxydqOverP[it] = (dx*dpxdqOverP[it]+dy*dpydqOverP[it])/PT-LXYoverPT*dPTdqOverP;
976 dLxydtheta[it] = (dx*dpxdtheta[it]+dy*dpydtheta[it])/PT-LXYoverPT*dPTdtheta;
977 dLxydphi[it] = (dx*dpxdphi[it]+dy*dpydphi[it])/PT-LXYoverPT*dPTdphi;
979 double dLxydx = Px/PT;
980 double dLxydy = Py/PT;
981 double dLxydx0 = -dLxydx;
982 double dLxydy0 = -dLxydy;
984 unsigned int ndim = 0;
985 if (fullCov.size() != 0) {
986 ndim = fullCov.rows();
992 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
994 for(
unsigned int it=0; it<NTrk; it++) {
997 D_vec(5*it+2) = dLxydphi[it];
998 D_vec(5*it+3) = dLxydtheta[it];
999 D_vec(5*it+4) = dLxydqOverP[it];
1001 D_vec(5*NTrk+0) = dLxydx;
1002 D_vec(5*NTrk+1) = dLxydy;
1003 D_vec(5*NTrk+2) = 0.;
1004 D_vec(5*NTrk+3) = dLxydx0;
1005 D_vec(5*NTrk+4) = dLxydy0;
1006 D_vec(5*NTrk+5) = 0.;
1008 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
1009 if (fullCov.size() != 0) {
1010 W_mat.block(0,0,ndim,ndim) = fullCov;
1013 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
1014 W_mat.block(5*NTrk,5*NTrk,3,3) = vxCandidate->covariancePosition();
1016 W_mat.block(5*NTrk+3,5*NTrk+3,3,3) =
vertex->covariancePosition();
1017 V0_err = D_vec.transpose() * W_mat * D_vec;
1018 }
else if (ndim == 3*NTrk+3) {
1023 for(
unsigned int it=0; it<NTrk; it++) {
1024 D_vec(3*it+3) = dLxydphi[it];
1025 D_vec(3*it+4) = dLxydtheta[it];
1026 D_vec(3*it+5) = dLxydqOverP[it];
1028 D_vec(3*NTrk+3) = dLxydx0;
1029 D_vec(3*NTrk+4) = dLxydy0;
1030 D_vec(3*NTrk+5) = 0.;
1032 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
1033 W_mat.block(0,0,ndim,ndim) = fullCov;
1034 W_mat.block(3*NTrk+3,3*NTrk+3,3,3) =
vertex->covariancePosition();
1035 V0_err = D_vec.transpose() * W_mat * D_vec;
1038 double LxyErrsq = V0_err(0,0);
1039 if (LxyErrsq <= 0.)
ATH_MSG_DEBUG(
"lxyError: negative sqrt LxyErrsq " << LxyErrsq);
1040 return (LxyErrsq>0.) ? sqrt(LxyErrsq) : 0.;
1046 double dx = vert.x();
1047 double dy = vert.y();
1048 double dz = vert.z();
1050 double dxyz= (mom.x()*dx + mom.y()*dy + mom.z()*dz)/mom.mag();
1057 double dx = vert.x();
1058 double dy = vert.y();
1059 double dz = vert.z();
1061 double Px=0., Py=0., Pz=0.;
1062 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
1063 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
1064 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk);
1065 std::vector<double>dLxyzdqOverP(NTrk), dLxyzdtheta(NTrk), dLxyzdphi(NTrk);
1068 for(
unsigned int it=0; it<NTrk; it++) {
1070 double trkCharge = 1.;
1071 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
1087 double Psq = Px*Px+Py*Py+Pz*Pz;
1088 double P = (Psq>0.) ? sqrt(Psq) : 0.;
1089 double LXYZoverP = (Px*dx+Py*dy+Pz*dz)/Psq;
1091 for(
unsigned int it=0; it<NTrk; it++) {
1092 double dPdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it])/
P;
1093 double dPdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/
P;
1094 double dPdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/
P;
1095 dLxyzdqOverP[it] = (dx*dpxdqOverP[it]+dy*dpydqOverP[it]+dz*dpzdqOverP[it])/
P-LXYZoverP*dPdqOverP;
1096 dLxyzdtheta[it] = (dx*dpxdtheta[it]+dy*dpydtheta[it]+dz*dpzdtheta[it])/
P-LXYZoverP*dPdtheta;
1097 dLxyzdphi[it] = (dx*dpxdphi[it]+dy*dpydphi[it])/
P-LXYZoverP*dPdphi;
1099 double dLxyzdx = Px/
P;
1100 double dLxyzdy = Py/
P;
1101 double dLxyzdz = Pz/
P;
1102 double dLxyzdx0 = -dLxyzdx;
1103 double dLxyzdy0 = -dLxyzdy;
1104 double dLxyzdz0 = -dLxyzdz;
1106 unsigned int ndim = 0;
1107 if (fullCov.size() != 0) {
1108 ndim = fullCov.rows();
1114 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
1116 for(
unsigned int it=0; it<NTrk; it++) {
1119 D_vec(5*it+2) = dLxyzdphi[it];
1120 D_vec(5*it+3) = dLxyzdtheta[it];
1121 D_vec(5*it+4) = dLxyzdqOverP[it];
1123 D_vec(5*NTrk+0) = dLxyzdx;
1124 D_vec(5*NTrk+1) = dLxyzdy;
1125 D_vec(5*NTrk+2) = dLxyzdz;
1126 D_vec(5*NTrk+3) = dLxyzdx0;
1127 D_vec(5*NTrk+4) = dLxyzdy0;
1128 D_vec(5*NTrk+5) = dLxyzdz0;
1130 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
1131 if (fullCov.size() != 0) {
1132 W_mat.block(0,0,ndim,ndim) = fullCov;
1135 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
1136 W_mat.block(5*NTrk,5*NTrk,3,3) = vxCandidate->covariancePosition();
1138 W_mat.block(5*NTrk+3,5*NTrk+3,3,3) =
vertex->covariancePosition();
1139 V0_err = D_vec.transpose() * W_mat * D_vec;
1140 }
else if (ndim == 3*NTrk+3) {
1145 for(
unsigned int it=0; it<NTrk; it++) {
1146 D_vec(3*it+3) = dLxyzdphi[it];
1147 D_vec(3*it+4) = dLxyzdtheta[it];
1148 D_vec(3*it+5) = dLxyzdqOverP[it];
1150 D_vec(3*NTrk+3) = dLxyzdx0;
1151 D_vec(3*NTrk+4) = dLxyzdy0;
1152 D_vec(3*NTrk+5) = dLxyzdz0;
1154 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
1155 W_mat.block(0,0,ndim,ndim) = fullCov;
1156 W_mat.block(3*NTrk+3,3*NTrk+3,3,3) =
vertex->covariancePosition();
1157 V0_err = D_vec.transpose() * W_mat * D_vec;
1160 double LxyzErrsq = V0_err(0,0);
1161 if (LxyzErrsq <= 0.)
ATH_MSG_DEBUG(
"lxyzError: negative sqrt LxyzErrsq " << LxyzErrsq);
1162 return (LxyzErrsq>0.) ? sqrt(LxyzErrsq) : 0.;
1167 std::array<double, 2> masses = {posTrackMass, negTrackMass};
1175 if (masses.size() != NTrk) {
1176 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
1180 double CONST = 1000./299.792;
1184 return CONST*M*LXY/PT;
1189 std::array<double, 2> masses = {posTrackMass, negTrackMass};
1191 return tau(vxCandidate,
vertex,masses,massV0);
1197 if (masses.size() != NTrk) {
1198 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
1204 double descr = cov(0,0)*cov(1,1)-cov(0,1)*cov(0,1);
1205 double cov_i11 = cov(1,1)/descr;
1206 double cov_i12 = -cov(0,1)/descr;
1207 double deltaTau = -(massV0-mass)*cov_i12/cov_i11;
1208 return Tau + deltaTau;
1214 double CONST = 1000./299.792;
1217 return CONST*M*LXY/PT;
1223 std::array<double, 2> masses = {posTrackMass, negTrackMass};
1232 if (masses.size() != NTrk) {
1233 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
1237 double CONST = 1000./299.792;
1240 double dx = vert.x();
1241 double dy = vert.y();
1243 double E=0., Px=0., Py=0., Pz=0.;
1244 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
1245 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
1246 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk), dedqOverP(NTrk);
1247 std::vector<double>dTaudqOverP(NTrk), dTaudtheta(NTrk), dTaudphi(NTrk);
1250 for(
unsigned int it=0; it<NTrk; it++) {
1252 double trkCharge = 1.;
1253 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
1257 double tmp = 1./(
qOverP*
qOverP) + masses[it]*masses[it];
1258 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
1273 double LXY = Px*dx+Py*dy;
1275 for(
unsigned int it=0; it<NTrk; it++) {
1276 double dMdqOverP = -(Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it]-E*dedqOverP[it])/M;
1277 double dMdtheta = -(Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/M;
1278 double dMdphi = -(Px*dpxdphi[it]+Py*dpydphi[it])/M;
1279 double dPTdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it])/PT;
1280 double dPTdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it])/PT;
1281 double dPTdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/PT;
1282 double dLXYdqOverP = dx*dpxdqOverP[it]+dy*dpydqOverP[it];
1283 double dLXYdtheta = dx*dpxdtheta[it]+dy*dpydtheta[it];
1284 double dLXYdphi = dx*dpxdphi[it]+dy*dpydphi[it];
1285 dTaudqOverP[it] = (LXY*dMdqOverP+M*dLXYdqOverP)/(PT*PT)-(2.*LXY*M*dPTdqOverP)/(PT*PT*PT);
1286 dTaudtheta[it] = (LXY*dMdtheta+M*dLXYdtheta)/(PT*PT)-(2.*LXY*M*dPTdtheta)/(PT*PT*PT);
1287 dTaudphi[it] = (LXY*dMdphi+M*dLXYdphi)/(PT*PT)-(2.*LXY*M*dPTdphi)/(PT*PT*PT);
1289 double dTaudx = (M*Px)/(PT*PT);
1290 double dTaudy = (M*Py)/(PT*PT);
1291 double dTaudx0 = -dTaudx;
1292 double dTaudy0 = -dTaudy;
1294 unsigned int ndim = 0;
1295 if (fullCov.size() != 0) {
1296 ndim = fullCov.rows();
1302 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
1304 for(
unsigned int it=0; it<NTrk; it++) {
1307 D_vec(5*it+2) = dTaudphi[it];
1308 D_vec(5*it+3) = dTaudtheta[it];
1309 D_vec(5*it+4) = dTaudqOverP[it];
1311 D_vec(5*NTrk+0) = dTaudx;
1312 D_vec(5*NTrk+1) = dTaudy;
1313 D_vec(5*NTrk+2) = 0.;
1314 D_vec(5*NTrk+3) = dTaudx0;
1315 D_vec(5*NTrk+4) = dTaudy0;
1316 D_vec(5*NTrk+5) = 0.;
1318 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
1319 if (fullCov.size() != 0) {
1320 W_mat.block(0,0,ndim,ndim) = fullCov;
1323 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
1324 W_mat.block(5*NTrk,5*NTrk,3,3) = vxCandidate->covariancePosition();
1326 W_mat.block(5*NTrk+3,5*NTrk+3,3,3) =
vertex->covariancePosition();
1327 V0_err = D_vec.transpose() * W_mat * D_vec;
1328 }
else if (ndim == 3*NTrk+3) {
1333 for(
unsigned int it=0; it<NTrk; it++) {
1334 D_vec(3*it+3) = dTaudphi[it];
1335 D_vec(3*it+4) = dTaudtheta[it];
1336 D_vec(3*it+5) = dTaudqOverP[it];
1338 D_vec(3*NTrk+3) = dTaudx0;
1339 D_vec(3*NTrk+4) = dTaudy0;
1340 D_vec(3*NTrk+5) = 0.;
1342 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
1343 W_mat.block(0,0,ndim,ndim) = fullCov;
1344 W_mat.block(3*NTrk+3,3*NTrk+3,3,3) =
vertex->covariancePosition();
1345 V0_err = D_vec.transpose() * W_mat * D_vec;
1348 double tauErrsq = V0_err(0,0);
1349 if (tauErrsq <= 0.)
ATH_MSG_DEBUG(
"tauError: negative sqrt tauErrsq " << tauErrsq);
1350 double tauErr = (tauErrsq>0.) ? sqrt(tauErrsq) : 0.;
1351 return CONST*tauErr;
1356 std::array<double, 2> masses = {posTrackMass, negTrackMass};
1364 if (masses.size() != NTrk) {
1365 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
1368 double error = -999999.;
1370 double descr = cov(0,0)*cov(1,1)-cov(0,1)*cov(0,1);
1371 double cov_i11 = cov(1,1)/descr;
1372 if (cov_i11 > 0.)
error = 1./sqrt(cov_i11);
1380 double CONST = 1000./299.792;
1383 double dx = vecsub.x();
1384 double dy = vecsub.y();
1386 double Px=0., Py=0.;
1387 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
1388 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
1389 std::vector<double>dPTdtheta(NTrk), dPTdphi(NTrk);
1390 std::vector<double>dTaudqOverP(NTrk), dTaudtheta(NTrk), dTaudphi(NTrk);
1393 for(
unsigned int it=0; it<NTrk; it++) {
1395 double trkCharge = 1.;
1396 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
1409 double LXY = Px*dx+Py*dy;
1411 for(
unsigned int it=0; it<NTrk; it++) {
1412 double dPTdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it])/PT;
1413 double dPTdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it])/PT;
1414 double dPTdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/PT;
1415 double dLXYdqOverP = dx*dpxdqOverP[it]+dy*dpydqOverP[it];
1416 double dLXYdtheta = dx*dpxdtheta[it]+dy*dpydtheta[it];
1417 double dLXYdphi = dx*dpxdphi[it]+dy*dpydphi[it];
1418 dTaudqOverP[it] = M*dLXYdqOverP/(PT*PT)-(2.*LXY*M*dPTdqOverP)/(PT*PT*PT);
1419 dTaudtheta[it] = M*dLXYdtheta/(PT*PT)-(2.*LXY*M*dPTdtheta)/(PT*PT*PT);
1420 dTaudphi[it] = M*dLXYdphi/(PT*PT)-(2.*LXY*M*dPTdphi)/(PT*PT*PT);
1422 double dTaudx = (M*Px)/(PT*PT);
1423 double dTaudy = (M*Py)/(PT*PT);
1424 double dTaudx0 = -dTaudx;
1425 double dTaudy0 = -dTaudy;
1427 unsigned int ndim = 0;
1428 if (fullCov.size() != 0) {
1429 ndim = fullCov.rows();
1435 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
1437 for(
unsigned int it=0; it<NTrk; it++) {
1440 D_vec(5*it+2) = dTaudphi[it];
1441 D_vec(5*it+3) = dTaudtheta[it];
1442 D_vec(5*it+4) = dTaudqOverP[it];
1444 D_vec(5*NTrk+0) = dTaudx;
1445 D_vec(5*NTrk+1) = dTaudy;
1446 D_vec(5*NTrk+2) = 0.;
1447 D_vec(5*NTrk+3) = dTaudx0;
1448 D_vec(5*NTrk+4) = dTaudy0;
1449 D_vec(5*NTrk+5) = 0.;
1451 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
1452 if (fullCov.size() != 0) {
1453 W_mat.block(0,0,ndim,ndim) = fullCov;
1456 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
1457 W_mat.block(5*NTrk,5*NTrk,3,3) = vxCandidate->covariancePosition();
1459 W_mat.block(5*NTrk+3,5*NTrk+3,3,3) =
vertex->covariancePosition();
1460 V0_err = D_vec.transpose() * W_mat * D_vec;
1461 }
else if (ndim == 3*NTrk+3) {
1466 for(
unsigned int it=0; it<NTrk; it++) {
1467 D_vec(3*it+3) = dTaudphi[it];
1468 D_vec(3*it+4) = dTaudtheta[it];
1469 D_vec(3*it+5) = dTaudqOverP[it];
1471 D_vec(3*NTrk+3) = dTaudx0;
1472 D_vec(3*NTrk+4) = dTaudy0;
1473 D_vec(3*NTrk+5) = 0.;
1475 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
1476 W_mat.block(0,0,ndim,ndim) = fullCov;
1477 W_mat.block(3*NTrk+3,3*NTrk+3,3,3) =
vertex->covariancePosition();
1478 V0_err = D_vec.transpose() * W_mat * D_vec;
1481 double tauErrsq = V0_err(0,0);
1482 if (tauErrsq <= 0.)
ATH_MSG_DEBUG(
"tauError: negative sqrt tauErrsq " << tauErrsq);
1483 double tauErr = (tauErrsq>0.) ? sqrt(tauErrsq) : 0.;
1484 return CONST*tauErr;
1490 if (masses.size() != NTrk) {
1491 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
1495 double CONST = 1000./299.792;
1499 return CONST*M*LXYZ/
P;
1505 double CONST = 1000./299.792;
1508 return CONST*M*LXYZ/
P;
1515 if (masses.size() != NTrk) {
1516 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
1520 double CONST = 1000./299.792;
1523 double dx = vert.x();
1524 double dy = vert.y();
1525 double dz = vert.z();
1527 double E=0., Px=0., Py=0., Pz=0.;
1528 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
1529 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
1530 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk), dedqOverP(NTrk);
1531 std::vector<double>dTaudqOverP(NTrk), dTaudtheta(NTrk), dTaudphi(NTrk);
1534 for(
unsigned int it=0; it<NTrk; it++) {
1536 double trkCharge = 1.;
1537 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
1541 double tmp = 1./(
qOverP*
qOverP) + masses[it]*masses[it];
1542 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
1557 double LXYZ = Px*dx+Py*dy+Pz*dz;
1559 for(
unsigned int it=0; it<NTrk; it++) {
1560 double dMdqOverP = -(Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it]-E*dedqOverP[it])/M;
1561 double dMdtheta = -(Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/M;
1562 double dMdphi = -(Px*dpxdphi[it]+Py*dpydphi[it])/M;
1563 double dPdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it])/
P;
1564 double dPdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/
P;
1565 double dPdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/
P;
1566 double dLXYZdqOverP = dx*dpxdqOverP[it]+dy*dpydqOverP[it]+dz*dpzdqOverP[it];
1567 double dLXYZdtheta = dx*dpxdtheta[it]+dy*dpydtheta[it]+dz*dpzdtheta[it];
1568 double dLXYZdphi = dx*dpxdphi[it]+dy*dpydphi[it];
1569 dTaudqOverP[it] = (LXYZ*dMdqOverP+M*dLXYZdqOverP)/(
P*
P)-(2.*LXYZ*M*dPdqOverP)/(
P*
P*
P);
1570 dTaudtheta[it] = (LXYZ*dMdtheta+M*dLXYZdtheta)/(
P*
P)-(2.*LXYZ*M*dPdtheta)/(
P*
P*
P);
1571 dTaudphi[it] = (LXYZ*dMdphi+M*dLXYZdphi)/(
P*
P)-(2.*LXYZ*M*dPdphi)/(
P*
P*
P);
1573 double dTaudx = (M*Px)/(
P*
P);
1574 double dTaudy = (M*Py)/(
P*
P);
1575 double dTaudz = (M*Pz)/(
P*
P);
1576 double dTaudx0 = -dTaudx;
1577 double dTaudy0 = -dTaudy;
1578 double dTaudz0 = -dTaudz;
1580 unsigned int ndim = 0;
1581 if (fullCov.size() != 0) {
1582 ndim = fullCov.rows();
1588 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
1590 for(
unsigned int it=0; it<NTrk; it++) {
1593 D_vec(5*it+2) = dTaudphi[it];
1594 D_vec(5*it+3) = dTaudtheta[it];
1595 D_vec(5*it+4) = dTaudqOverP[it];
1597 D_vec(5*NTrk+0) = dTaudx;
1598 D_vec(5*NTrk+1) = dTaudy;
1599 D_vec(5*NTrk+2) = dTaudz;
1600 D_vec(5*NTrk+3) = dTaudx0;
1601 D_vec(5*NTrk+4) = dTaudy0;
1602 D_vec(5*NTrk+5) = dTaudz0;
1604 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
1605 if (fullCov.size() != 0) {
1606 W_mat.block(0,0,ndim,ndim) = fullCov;
1609 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
1610 W_mat.block(5*NTrk,5*NTrk,3,3) = vxCandidate->covariancePosition();
1612 W_mat.block(5*NTrk+3,5*NTrk+3,3,3) =
vertex->covariancePosition();
1613 V0_err = D_vec.transpose() * W_mat * D_vec;
1614 }
else if (ndim == 3*NTrk+3) {
1619 for(
unsigned int it=0; it<NTrk; it++) {
1620 D_vec(3*it+3) = dTaudphi[it];
1621 D_vec(3*it+4) = dTaudtheta[it];
1622 D_vec(3*it+5) = dTaudqOverP[it];
1624 D_vec(3*NTrk+3) = dTaudx0;
1625 D_vec(3*NTrk+4) = dTaudy0;
1626 D_vec(3*NTrk+5) = dTaudz0;
1628 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
1629 W_mat.block(0,0,ndim,ndim) = fullCov;
1630 W_mat.block(3*NTrk+3,3*NTrk+3,3,3) =
vertex->covariancePosition();
1631 V0_err = D_vec.transpose() * W_mat * D_vec;
1634 double tauErrsq = V0_err(0,0);
1635 if (tauErrsq <= 0.)
ATH_MSG_DEBUG(
"tauError: negative sqrt tauErrsq " << tauErrsq);
1636 double tauErr = (tauErrsq>0.) ? sqrt(tauErrsq) : 0.;
1637 return CONST*tauErr;
1644 double CONST = 1000./299.792;
1647 double dx = vecsub.x();
1648 double dy = vecsub.y();
1649 double dz = vecsub.z();
1651 double Px=0., Py=0., Pz=0.;
1652 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
1653 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
1654 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk);
1655 std::vector<double>dTaudqOverP(NTrk), dTaudtheta(NTrk), dTaudphi(NTrk);
1658 for(
unsigned int it=0; it<NTrk; it++) {
1660 double trkCharge = 1.;
1661 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
1677 double LXYZ = Px*dx+Py*dy+Pz*dz;
1679 for(
unsigned int it=0; it<NTrk; it++) {
1680 double dPdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it])/
P;
1681 double dPdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/
P;
1682 double dPdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/
P;
1683 double dLXYZdqOverP = dx*dpxdqOverP[it]+dy*dpydqOverP[it]+dz*dpzdqOverP[it];
1684 double dLXYZdtheta = dx*dpxdtheta[it]+dy*dpydtheta[it]+dz*dpzdtheta[it];
1685 double dLXYZdphi = dx*dpxdphi[it]+dy*dpydphi[it];
1686 dTaudqOverP[it] = M*dLXYZdqOverP/(
P*
P)-(2.*LXYZ*M*dPdqOverP)/(
P*
P*
P);
1687 dTaudtheta[it] = M*dLXYZdtheta/(
P*
P)-(2.*LXYZ*M*dPdtheta)/(
P*
P*
P);
1688 dTaudphi[it] = M*dLXYZdphi/(
P*
P)-(2.*LXYZ*M*dPdphi)/(
P*
P*
P);
1690 double dTaudx = (M*Px)/(
P*
P);
1691 double dTaudy = (M*Py)/(
P*
P);
1692 double dTaudz = (M*Pz)/(
P*
P);
1693 double dTaudx0 = -dTaudx;
1694 double dTaudy0 = -dTaudy;
1695 double dTaudz0 = -dTaudz;
1697 unsigned int ndim = 0;
1698 if (fullCov.size() != 0) {
1699 ndim = fullCov.rows();
1705 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
1707 for(
unsigned int it=0; it<NTrk; it++) {
1710 D_vec(5*it+2) = dTaudphi[it];
1711 D_vec(5*it+3) = dTaudtheta[it];
1712 D_vec(5*it+4) = dTaudqOverP[it];
1714 D_vec(5*NTrk+0) = dTaudx;
1715 D_vec(5*NTrk+1) = dTaudy;
1716 D_vec(5*NTrk+2) = dTaudz;
1717 D_vec(5*NTrk+3) = dTaudx0;
1718 D_vec(5*NTrk+4) = dTaudy0;
1719 D_vec(5*NTrk+5) = dTaudz0;
1721 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
1722 if (fullCov.size() != 0) {
1723 W_mat.block(0,0,ndim,ndim) = fullCov;
1726 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
1727 W_mat.block(5*NTrk,5*NTrk,3,3) = vxCandidate->covariancePosition();
1729 W_mat.block(5*NTrk+3,5*NTrk+3,3,3) =
vertex->covariancePosition();
1730 V0_err = D_vec.transpose() * W_mat * D_vec;
1731 }
else if (ndim == 3*NTrk+3) {
1736 for(
unsigned int it=0; it<NTrk; it++) {
1737 D_vec(3*it+3) = dTaudphi[it];
1738 D_vec(3*it+4) = dTaudtheta[it];
1739 D_vec(3*it+5) = dTaudqOverP[it];
1741 D_vec(3*NTrk+3) = dTaudx0;
1742 D_vec(3*NTrk+4) = dTaudy0;
1743 D_vec(3*NTrk+5) = dTaudz0;
1745 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
1746 W_mat.block(0,0,ndim,ndim) = fullCov;
1747 W_mat.block(3*NTrk+3,3*NTrk+3,3,3) =
vertex->covariancePosition();
1748 V0_err = D_vec.transpose() * W_mat * D_vec;
1751 double tauErrsq = V0_err(0,0);
1752 if (tauErrsq <= 0.)
ATH_MSG_DEBUG(
"tauError: negative sqrt tauErrsq " << tauErrsq);
1753 double tauErr = (tauErrsq>0.) ? sqrt(tauErrsq) : 0.;
1754 return CONST*tauErr;
1762 CLHEP::HepLorentzVector v1(V1.Px(),V1.Py(),V1.Pz(),V1.E());
1763 CLHEP::HepLorentzVector v2(V2.Px(),V2.Py(),V2.Pz(),V2.E());
1764 CLHEP::HepLorentzVector v0 = v1 + v2;
1765 CLHEP::Hep3Vector boost_v0 = v0.boostVector();
1767 v1.boost( boost_v0 );
1768 v2.boost( boost_v0 );
1769 theta = v0.angle( v1.vect() );
1777 CLHEP::HepLorentzVector posMom(PosMom.Px(),PosMom.Py(),PosMom.Pz(),PosMom.E());
1778 CLHEP::HepLorentzVector negMom(NegMom.Px(),NegMom.Py(),NegMom.Pz(),NegMom.E());
1784 CLHEP::HepLorentzVector v0(posTrack + negTrack);
1785 double Mv0 = v0.m();
1786 double Mplus = posTrack.m();
1787 double Mminus= negTrack.m();
1788 double Pv0 = v0.rho();
1789 double pssq = (Mv0*Mv0-(Mplus+Mminus)*(Mplus+Mminus))*(Mv0*Mv0-(Mplus-Mminus)*(Mplus-Mminus));
1790 double ps = (pssq>0.) ? sqrt(pssq) : 0.;
1792 double pp = v0.px()*posTrack.px() + v0.py()*posTrack.py() + v0.pz()*posTrack.pz();
1793 return ( v0.e()*pp - Pv0*Pv0*posTrack.e())/( Mv0*ps*Pv0);
1801 CLHEP::HepLorentzVector v_pos(V_pos.Px(),V_pos.Py(),V_pos.Pz(),V_pos.E());
1802 CLHEP::HepLorentzVector v_neg(V_neg.Px(),V_neg.Py(),V_neg.Pz(),V_neg.E());
1803 return phiStar(v_pos+v_neg,v_pos);
1806 double V0Tools::phiStar(
const CLHEP::HepLorentzVector & v0,
const CLHEP::HepLorentzVector & track)
1809 CLHEP::Hep3Vector V0 = v0.getV();
1810 CLHEP::Hep3Vector trk = track.getV();
1812 trk.rotateZ(-V0.phi());
1813 trk.rotateY(-V0.theta());
1820 phiStar = atan2(trk.y(),trk.x());
1827 auto vtx1 =
vtx(vxCandidate);
1829 return (mom.dot(vtx1))/(mom.mag()*(vtx1).
mag());
1835 auto vtx1 =
vtx(vxCandidate);
1836 vtx1 -=
vertex->position();
1837 return (mom.dot((vtx1)))/(mom.mag()*(vtx1).
mag());
1843 auto vtx1 =
vtx(vxCandidate);
1845 double pT = mom.perp();
1846 return (mom.x()*vtx1.x()+mom.y()*vtx1.y())/(
pT*vtx1.perp());
1852 auto vtx1 =
vtx(vxCandidate);
1853 vtx1 -=
vertex->position();
1854 double pT = mom.perp();
1855 return (mom.x()*vtx1.x()+mom.y()*vtx1.y())/(
pT*vtx1.perp());
1862 for(
unsigned int it=0; it<NTrk; it++) {
1881 if (NTrk != 2)
return origTrk;
1882 for(
unsigned int it=0; it<NTrk; it++) {
1892 if (NTrk != 2)
return origTrk;
1893 for(
unsigned int it=0; it<NTrk; it++) {
2142 double px = 0.,
py = 0.,
pz = 0., e = 0.;
2144 if (masses.size() != NTrk) {
2145 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
2148 for(
unsigned int it=0; it<NTrk; it++) {
2149 if (masses[it] >= 0.) {
2151 if (TP ==
nullptr)
return -999999.;
2152 TLorentzVector
Tp4 = TP->
p4();
2156 double pesq = 1./(TP->
qOverP()*TP->
qOverP()) + masses[it]*masses[it];
2157 double pe = (pesq>0.) ? sqrt(pesq) : 0.;
2162 return (msq>0.) ? sqrt(msq) : 0.;
2168 double px = 0.,
py = 0.,
pz = 0., e = 0.;
2170 if (masses.size() != NTrk) {
2171 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
2174 for(
unsigned int it=0; it<NTrk; it++) {
2175 if (masses[it] >= 0.) {
2177 if (TP ==
nullptr)
return -999999.;
2178 std::unique_ptr<const Trk::TrackParameters> extrPer =
2180 if (extrPer ==
nullptr)
2182 px += extrPer->momentum().x();
2183 py += extrPer->momentum().y();
2184 pz += extrPer->momentum().z();
2185 double pesq = extrPer->momentum().mag2() + masses[it]*masses[it];
2186 double pe = (pesq>0.) ? sqrt(pesq) : 0.;
2191 return (msq>0.) ? sqrt(msq) : 0.;
2198 double px = 0.,
py = 0.,
pz = 0., e = 0.;
2200 if (masses.size() != NTrk) {
2201 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
2204 for(
unsigned int it=0; it<NTrk; it++) {
2205 if (masses[it] >= 0.) {
2207 if (TP ==
nullptr)
return -999999.;
2208 std::unique_ptr<const Trk::TrackParameters> extrPer =
2210 if (extrPer ==
nullptr)
2212 px += extrPer->momentum().x();
2213 py += extrPer->momentum().y();
2214 pz += extrPer->momentum().z();
2215 double pesq = extrPer->momentum().mag2() + masses[it]*masses[it];
2216 double pe = (pesq>0.) ? sqrt(pesq) : 0.;
2221 return (msq>0.) ? sqrt(msq) : 0.;
2227 if (masses.size() != NTrk) {
2228 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
2232 double E=0., Px=0., Py=0., Pz=0.;
2234 std::vector<double>dm2dphi(NTrk), dm2dtheta(NTrk), dm2dqOverP(NTrk);
2236 for(
unsigned int it=0; it<NTrk; it++) {
2237 if (masses[it] >= 0.) {
2239 if (TP ==
nullptr)
return -999999.;
2241 V0_cor(5*it+2,5*it+2) = cov_tmp(2,2);
2242 V0_cor(5*it+2,5*it+3) = cov_tmp(2,3);
2243 V0_cor(5*it+2,5*it+4) = cov_tmp(2,4);
2244 V0_cor(5*it+3,5*it+3) = cov_tmp(3,3);
2245 V0_cor(5*it+3,5*it+4) = cov_tmp(3,4);
2246 V0_cor(5*it+4,5*it+4) = cov_tmp(4,4);
2247 V0_cor(5*it+3,5*it+2) = cov_tmp(2,3);
2248 V0_cor(5*it+4,5*it+2) = cov_tmp(2,4);
2249 V0_cor(5*it+4,5*it+3) = cov_tmp(3,4);
2254 double tmp = 1./(
qOverP[it]*
qOverP[it]) + masses[it]*masses[it];
2255 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
2258 TLorentzVector p4 = TP->
p4();
2265 for(
unsigned int it=0; it<NTrk; it++) {
2266 if (masses[it] >= 0.) {
2274 for(
unsigned int it=0; it<NTrk; it++) {
2275 D_vec(5*it+0,0) = 0.;
2276 D_vec(5*it+1,0) = 0.;
2277 D_vec(5*it+2,0) = dm2dphi[it];
2278 D_vec(5*it+3,0) = dm2dtheta[it];
2279 D_vec(5*it+4,0) = dm2dqOverP[it];
2281 Amg::MatrixX V0_merr = D_vec.transpose() * V0_cor * D_vec;
2283 double massVarsq = V0_merr(0,0);
2284 if (massVarsq <= 0.)
ATH_MSG_DEBUG(
"massError: negative sqrt massVarsq " << massVarsq);
2285 double massVar = (massVarsq>0.) ? sqrt(massVarsq) : 0.;
2286 double massErr = massVar/(2.*mass);
2294 if (masses.size() != NTrk) {
2295 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
2307 if (masses.size() != NTrk) {
2308 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
2312 double E=0., Px=0., Py=0., Pz=0.;
2314 std::vector<double>dm2dphi(NTrk), dm2dtheta(NTrk), dm2dqOverP(NTrk);
2316 for(
unsigned int it=0; it<NTrk; it++) {
2317 if (masses[it] >= 0.) {
2319 if (TP ==
nullptr)
return -999999.;
2320 std::unique_ptr<const Trk::TrackParameters> extrPer =
2322 if (extrPer ==
nullptr)
2324 const AmgSymMatrix(5)* cov_tmp = extrPer->covariance();
2325 V0_cor(5*it+2,5*it+2) = (*cov_tmp)(2,2);
2326 V0_cor(5*it+2,5*it+3) = (*cov_tmp)(2,3);
2327 V0_cor(5*it+2,5*it+4) = (*cov_tmp)(2,4);
2328 V0_cor(5*it+3,5*it+3) = (*cov_tmp)(3,3);
2329 V0_cor(5*it+3,5*it+4) = (*cov_tmp)(3,4);
2330 V0_cor(5*it+4,5*it+4) = (*cov_tmp)(4,4);
2331 V0_cor(5*it+3,5*it+2) = (*cov_tmp)(2,3);
2332 V0_cor(5*it+4,5*it+2) = (*cov_tmp)(2,4);
2333 V0_cor(5*it+4,5*it+3) = (*cov_tmp)(3,4);
2338 double tmp = 1./(
qOverP[it]*
qOverP[it]) + masses[it]*masses[it];
2339 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
2342 Px += extrPer->momentum().x();
2343 Py += extrPer->momentum().y();
2344 Pz += extrPer->momentum().z();
2347 double msq = E*E - Px*Px - Py*Py - Pz*Pz;
2348 double mass = (msq>0.) ? sqrt(msq) : 0.;
2350 for(
unsigned int it=0; it<NTrk; it++) {
2351 if (masses[it] >= 0.) {
2359 for(
unsigned int it=0; it<NTrk; it++) {
2360 D_vec(5*it+0,0) = 0.;
2361 D_vec(5*it+1,0) = 0.;
2362 D_vec(5*it+2,0) = dm2dphi[it];
2363 D_vec(5*it+3,0) = dm2dtheta[it];
2364 D_vec(5*it+4,0) = dm2dqOverP[it];
2366 Amg::MatrixX V0_merr = D_vec.transpose() * V0_cor * D_vec;
2368 double massVarsq = V0_merr(0,0);
2369 if (massVarsq <= 0.)
ATH_MSG_DEBUG(
"massError: negative sqrt massVarsq " << massVarsq);
2370 double massVar = (massVarsq>0.) ? sqrt(massVarsq) : 0.;
2371 double massErr = massVar/(2.*mass);
2380 if (masses.size() != NTrk) {
2381 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
2385 double CONST = 1000./299.792;
2388 double dx = vert.x();
2389 double dy = vert.y();
2391 double E=0., Px=0., Py=0., Pz=0.;
2392 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
2393 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
2394 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk), dedqOverP(NTrk);
2395 std::vector<double>dMdqOverP(NTrk), dMdtheta(NTrk), dMdphi(NTrk);
2396 std::vector<double>dTaudqOverP(NTrk), dTaudtheta(NTrk), dTaudphi(NTrk);
2399 for(
unsigned int it=0; it<NTrk; it++) {
2401 double trkCharge = 1.;
2402 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
2406 double tmp = 1./(
qOverP*
qOverP) + masses[it]*masses[it];
2407 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
2422 double LXY = Px*dx+Py*dy;
2424 for(
unsigned int it=0; it<NTrk; it++) {
2425 dMdqOverP[it] = -(Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it]-E*dedqOverP[it])/M;
2426 dMdtheta[it] = -(Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/M;
2427 dMdphi[it] = -(Px*dpxdphi[it]+Py*dpydphi[it])/M;
2428 double dPTdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it])/PT;
2429 double dPTdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it])/PT;
2430 double dPTdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/PT;
2431 double dLXYdqOverP = dx*dpxdqOverP[it]+dy*dpydqOverP[it];
2432 double dLXYdtheta = dx*dpxdtheta[it]+dy*dpydtheta[it];
2433 double dLXYdphi = dx*dpxdphi[it]+dy*dpydphi[it];
2434 dTaudqOverP[it] = (LXY*dMdqOverP[it]+M*dLXYdqOverP)/(PT*PT)-(2.*LXY*M*dPTdqOverP)/(PT*PT*PT);
2435 dTaudtheta[it] = (LXY*dMdtheta[it]+M*dLXYdtheta)/(PT*PT)-(2.*LXY*M*dPTdtheta)/(PT*PT*PT);
2436 dTaudphi[it] = (LXY*dMdphi[it]+M*dLXYdphi)/(PT*PT)-(2.*LXY*M*dPTdphi)/(PT*PT*PT);
2438 double dTaudx = (M*Px)/(PT*PT);
2439 double dTaudy = (M*Py)/(PT*PT);
2440 double dTaudx0 = -dTaudx;
2441 double dTaudy0 = -dTaudy;
2443 unsigned int ndim = 0;
2444 if (fullCov.size() != 0) {
2445 ndim = fullCov.rows();
2451 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
2453 for(
unsigned int it=0; it<NTrk; it++) {
2454 D_mat(5*it+0,0) = 0.;
2455 D_mat(5*it+1,0) = 0.;
2456 D_mat(5*it+2,0) = CONST*dTaudphi[it];
2457 D_mat(5*it+3,0) = CONST*dTaudtheta[it];
2458 D_mat(5*it+4,0) = CONST*dTaudqOverP[it];
2459 D_mat(5*it+0,1) = 0.;
2460 D_mat(5*it+1,1) = 0.;
2461 D_mat(5*it+2,1) = dMdphi[it];
2462 D_mat(5*it+3,1) = dMdtheta[it];
2463 D_mat(5*it+4,1) = dMdqOverP[it];
2465 D_mat(5*NTrk+0,0) = CONST*dTaudx;
2466 D_mat(5*NTrk+1,0) = CONST*dTaudy;
2467 D_mat(5*NTrk+2,0) = 0.;
2468 D_mat(5*NTrk+3,0) = CONST*dTaudx0;
2469 D_mat(5*NTrk+4,0) = CONST*dTaudy0;
2470 D_mat(5*NTrk+5,0) = 0.;
2471 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
2472 if (fullCov.size() != 0) {
2473 W_mat.block(0,0,ndim,ndim) = fullCov;
2476 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
2477 W_mat.block(5*NTrk,5*NTrk,3,3) = vxCandidate->covariancePosition();
2479 W_mat.block(5*NTrk+3,5*NTrk+3,3,3) =
vertex->covariancePosition();
2480 V0_err = D_mat.transpose() * W_mat * D_mat;
2481 }
else if (ndim == 3*NTrk+3) {
2483 D_mat(0,0) = CONST*dTaudx;
2484 D_mat(1,0) = CONST*dTaudy;
2486 for(
unsigned int it=0; it<NTrk; it++) {
2487 D_mat(3*it+3,0) = CONST*dTaudphi[it];
2488 D_mat(3*it+4,0) = CONST*dTaudtheta[it];
2489 D_mat(3*it+5,0) = CONST*dTaudqOverP[it];
2490 D_mat(3*it+3,1) = dMdphi[it];
2491 D_mat(3*it+4,1) = dMdtheta[it];
2492 D_mat(3*it+5,1) = dMdqOverP[it];
2494 D_mat(3*NTrk+3,0) = CONST*dTaudx0;
2495 D_mat(3*NTrk+4,0) = CONST*dTaudy0;
2496 D_mat(3*NTrk+5,0) = 0.;
2497 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
2498 W_mat.block(0,0,ndim,ndim) = fullCov;
2499 W_mat.block(3*NTrk+3,3*NTrk+3,3,3) =
vertex->covariancePosition();
2500 V0_err = D_mat.transpose() * W_mat * D_mat;
2508 for(
unsigned int it=0; it<NTrk; it++){
2511 V0_cov(5*it+2,5*it+2) = (*cov_tmp)(2,2);
2512 V0_cov(5*it+2,5*it+3) = (*cov_tmp)(2,3);
2513 V0_cov(5*it+2,5*it+4) = (*cov_tmp)(2,4);
2514 V0_cov(5*it+3,5*it+3) = (*cov_tmp)(3,3);
2515 V0_cov(5*it+3,5*it+4) = (*cov_tmp)(3,4);
2516 V0_cov(5*it+4,5*it+4) = (*cov_tmp)(4,4);
2517 V0_cov(5*it+3,5*it+2) = (*cov_tmp)(2,3);
2518 V0_cov(5*it+4,5*it+2) = (*cov_tmp)(2,4);
2519 V0_cov(5*it+4,5*it+3) = (*cov_tmp)(3,4);
2529 if (masses.size() != NTrk) {
2530 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
2534 double CONST = 1000./299.792;
2537 double dx = vert.x();
2538 double dy = vert.y();
2540 double E=0., Px=0., Py=0., Pz=0.;
2541 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
2542 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
2543 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk), dedqOverP(NTrk);
2544 std::vector<double>dMdqOverP(NTrk), dMdtheta(NTrk), dMdphi(NTrk);
2545 std::vector<double>dTaudqOverP(NTrk), dTaudtheta(NTrk), dTaudphi(NTrk);
2548 for(
unsigned int it=0; it<NTrk; it++) {
2550 double trkCharge = 1.;
2551 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
2555 double tmp = 1./(
qOverP*
qOverP) + masses[it]*masses[it];
2556 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
2571 double LXY = Px*dx+Py*dy;
2573 for(
unsigned int it=0; it<NTrk; it++) {
2574 dMdqOverP[it] = -(Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it]-E*dedqOverP[it])/M;
2575 dMdtheta[it] = -(Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/M;
2576 dMdphi[it] = -(Px*dpxdphi[it]+Py*dpydphi[it])/M;
2577 double dPTdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it])/PT;
2578 double dPTdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it])/PT;
2579 double dPTdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/PT;
2580 double dLXYdqOverP = dx*dpxdqOverP[it]+dy*dpydqOverP[it];
2581 double dLXYdtheta = dx*dpxdtheta[it]+dy*dpydtheta[it];
2582 double dLXYdphi = dx*dpxdphi[it]+dy*dpydphi[it];
2583 dTaudqOverP[it] = (LXY*dMdqOverP[it]+M*dLXYdqOverP)/(PT*PT)-(2.*LXY*M*dPTdqOverP)/(PT*PT*PT);
2584 dTaudtheta[it] = (LXY*dMdtheta[it]+M*dLXYdtheta)/(PT*PT)-(2.*LXY*M*dPTdtheta)/(PT*PT*PT);
2585 dTaudphi[it] = (LXY*dMdphi[it]+M*dLXYdphi)/(PT*PT)-(2.*LXY*M*dPTdphi)/(PT*PT*PT);
2587 double dTaudx = (M*Px)/(PT*PT);
2588 double dTaudy = (M*Py)/(PT*PT);
2589 double dTaudx0 = -dTaudx;
2590 double dTaudy0 = -dTaudy;
2592 unsigned int ndim = 0;
2593 if (fullCov.size() != 0) {
2594 ndim = fullCov.rows();
2599 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
2601 for(
unsigned int it=0; it<NTrk; it++) {
2602 D_mat(5*it+0,0) = 0.;
2603 D_mat(5*it+1,0) = 0.;
2604 D_mat(5*it+2,0) = CONST*dTaudphi[it];
2605 D_mat(5*it+3,0) = CONST*dTaudtheta[it];
2606 D_mat(5*it+4,0) = CONST*dTaudqOverP[it];
2607 D_mat(5*it+0,1) = 0.;
2608 D_mat(5*it+1,1) = 0.;
2609 D_mat(5*it+2,1) = dMdphi[it];
2610 D_mat(5*it+3,1) = dMdtheta[it];
2611 D_mat(5*it+4,1) = dMdqOverP[it];
2613 D_mat(5*NTrk+0,0) = CONST*dTaudx;
2614 D_mat(5*NTrk+1,0) = CONST*dTaudy;
2615 D_mat(5*NTrk+2,0) = 0.;
2616 D_mat(5*NTrk+3,0) = CONST*dTaudx0;
2617 D_mat(5*NTrk+4,0) = CONST*dTaudy0;
2618 D_mat(5*NTrk+5,0) = 0.;
2619 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
2620 if (fullCov.size() != 0) {
2621 W_mat.block(0,0,ndim,ndim) = fullCov;
2624 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
2625 W_mat.block(5*NTrk,5*NTrk,3,3) = vxCandidate->covariancePosition();
2627 W_mat.block(5*NTrk+3,5*NTrk,3,3) =
vertex->covariancePosition();
2628 V0_err = D_mat.transpose() * W_mat * D_mat;
2629 }
else if (ndim == 3*NTrk+3) {
2631 D_mat(0,0) = CONST*dTaudx;
2632 D_mat(1,0) = CONST*dTaudy;
2634 for(
unsigned int it=0; it<NTrk; it++) {
2635 D_mat(3*it+3,0) = CONST*dTaudphi[it];
2636 D_mat(3*it+4,0) = CONST*dTaudtheta[it];
2637 D_mat(3*it+5,0) = CONST*dTaudqOverP[it];
2638 D_mat(3*it+3,1) = dMdphi[it];
2639 D_mat(3*it+4,1) = dMdtheta[it];
2640 D_mat(3*it+5,1) = dMdqOverP[it];
2642 D_mat(3*NTrk+3,0) = CONST*dTaudx0;
2643 D_mat(3*NTrk+4,0) = CONST*dTaudy0;
2644 D_mat(3*NTrk+5,0) = 0.;
2645 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
2646 W_mat.block(0,0,ndim,ndim) = fullCov;
2647 W_mat.block(3*NTrk+3,3*NTrk+3,3,3) =
vertex->covariancePosition();
2648 V0_err = D_mat.transpose() * W_mat * D_mat;
2656 const std::vector<float> &matrix = vxCandidate->
covariance();
2660 if ( matrix.size() == (3*NTrk+3)*(3*NTrk+3+1)/2) {
2662 }
else if (matrix.size() == (5*NTrk+3)*(5*NTrk+3+1)/2) {
2671 for (
int i=1; i<= ndim; i++) {
2672 for (
int j=1; j<=i; j++){
2674 mtx(i-1,j-1)=matrix[ij];
2676 mtx.fillSymmetric(i-1,j-1,matrix[ij]);
Scalar mag() const
mag method
#define AmgSymMatrix(dim)
#define AmgMatrix(rows, cols)
const Amg::Vector3D & momentum() const
Access method for the momentum.
Class describing the Line to which the Perigee refers to.
float theta() const
Returns the parameter, which has range 0 to .
virtual FourMom_t p4() const override final
The full 4-momentum of the particle.
const Trk::Perigee & perigeeParameters() const
Returns the Trk::MeasuredPerigee track parameters.
IParticle::FourMom_t FourMom_t
Definition of the 4-momentum type.
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .)
const ParametersCovMatrix_t definingParametersCovMatrix() const
Returns the 5x5 symmetric matrix containing the defining parameters covariance matrix.
float qOverP() const
Returns the parameter.
float charge() const
Returns the charge.
size_t nTrackParticles() const
Get the number of tracks associated with this vertex.
const TrackParticle * trackParticle(size_t i) const
Get the pointer to a given track that was used in vertex reco.
float numberDoF() const
Returns the number of degrees of freedom of the vertex fit as float.
float chiSquared() const
Returns the of the vertex fit as float.
std::vector< Trk::VxTrackAtVertex > & vxTrackAtVertex()
Non-const access to the VxTrackAtVertex vector.
const Amg::Vector3D & position() const
Returns the 3-pos.
const std::vector< float > & covariance() const
Returns the covariance matrix as a simple vector of values.
double chi2(TH1 *h0, TH1 *h1)
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > SymMatrixX
Eigen::Matrix< double, 3, 1 > Vector3D
Ensure that the ATLAS eigen extensions are properly loaded.
@ pz
global momentum (cartesian)
ParametersBase< TrackParametersDim, Charged > TrackParameters
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.