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_ERROR(
"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_ERROR(
"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_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
117 if (fullCov.size() == 0)
return -999999.;
118 double E=0., Px=0., Py=0., Pz=0.;
120 std::vector<double>dm2dphi(NTrk), dm2dtheta(NTrk), dm2dqOverP(NTrk);
121 for(
unsigned int it=0; it<NTrk; it++) {
122 if (masses[it] >= 0.) {
124 double trkCharge = 1.;
125 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
130 double tmp = 1./(
qOverP[it]*
qOverP[it]) + masses[it]*masses[it];
131 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
139 double msq = E*E - Px*Px - Py*Py - Pz*Pz;
140 double mass = (msq>0.) ? sqrt(msq) : 0.;
142 for(
unsigned int it=0; it<NTrk; it++) {
143 if (masses[it] >= 0.) {
151 for(
unsigned int it=0; it<NTrk; it++) {
152 D_vec(5*it+0,0) = 0.;
153 D_vec(5*it+1,0) = 0.;
154 D_vec(5*it+2,0) = dm2dphi[it];
155 D_vec(5*it+3,0) = dm2dtheta[it];
156 D_vec(5*it+4,0) = dm2dqOverP[it];
158 Amg::MatrixX V0_merr = D_vec.transpose() * fullCov.block(0,0,5*NTrk,5*NTrk) * D_vec;
160 double massVarsq = V0_merr(0,0);
161 if (massVarsq <= 0.)
ATH_MSG_DEBUG(
"massError: negative sqrt massVarsq " << massVarsq);
162 double massVar = (massVarsq>0.) ? sqrt(massVarsq) : 0.;
163 double massErr = massVar/(2.*mass);
169 std::array<double, 2> masses = {posTrackMass, negTrackMass};
176 if (masses.size() != NTrk) {
177 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
180 std::vector<xAOD::TrackParticle::FourMom_t> particleMom(NTrk);
181 std::vector<
AmgMatrix(3,3)> particleDeriv(NTrk);
183 AmgMatrix(3,3) tmpDeriv; tmpDeriv.setZero();
185 if (fullCov.size() == 0)
return -999999.;
187 for(
unsigned int it=0; it<NTrk; it++){
188 if (masses[it] >= 0.) {
195 double pz = cos(
theta)/fabs(invP);
196 double esq =
px*
px +
py*
py +
pz*
pz + masses[it]*masses[it];
197 double e = (esq>0.) ? sqrt(esq) : 0.;
199 tmp.SetPxPyPzE(
px,
py,
pz,e);
200 particleMom[it] = tmp;
204 tmpDeriv(0,0) = - tmp.Py();
205 tmpDeriv(1,0) = tmp.Px();
207 tmpDeriv(0,1) = cos(
phi) * tmp.Pz();
208 tmpDeriv(1,1) = sin(
phi) * tmp.Pz();
209 tmpDeriv(2,1) = - sin(
theta)/fabs(invP);
210 tmpDeriv(0,2) = - tmp.Px()/invP;
211 tmpDeriv(1,2) = - tmp.Py()/invP;
212 tmpDeriv(2,2) = - tmp.Pz()/invP;
213 particleDeriv[it] = tmpDeriv;
217 std::vector<double> Deriv(3*NTrk+3, 0.);
218 for(
unsigned int it=0; it<NTrk; it++){
219 if (masses[it] >= 0.) {
220 double dMdPx = ( totalMom.E() * particleMom[it].Px()/particleMom[it].E() - totalMom.Px() ) / totalMom.M();
221 double dMdPy = ( totalMom.E() * particleMom[it].Py()/particleMom[it].E() - totalMom.Py() ) / totalMom.M();
222 double dMdPz = ( totalMom.E() * particleMom[it].Pz()/particleMom[it].E() - totalMom.Pz() ) / totalMom.M();
224 double dMdPhi = dMdPx*particleDeriv[it](0,0) + dMdPy*particleDeriv[it](1,0) + dMdPz*particleDeriv[it](2,0);
225 double dMdTheta = dMdPx*particleDeriv[it](0,1) + dMdPy*particleDeriv[it](1,1) + dMdPz*particleDeriv[it](2,1);
226 double dMdInvP = dMdPx*particleDeriv[it](0,2) + dMdPy*particleDeriv[it](1,2) + dMdPz*particleDeriv[it](2,2);
228 Deriv[3*it + 3 + 0] = dMdPhi; Deriv[3*it + 3 + 1] = dMdTheta; Deriv[3*it + 3 + 2] = dMdInvP;
233 for(
unsigned int i=0; i<3*NTrk+3; i++){
234 for(
unsigned int j=0; j<3*NTrk+3; j++){
235 err += Deriv[i]*( fullCov)(i,j)*Deriv[j];
238 if (err <= 0.)
ATH_MSG_DEBUG(
"massError: negative sqrt err " << err);
239 return (err>0.) ? sqrt(err) : 0.;
244 std::array<double, 2> masses = {posTrackMass, negTrackMass};
252 if (masses.size() != NTrk) {
253 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
256 double E=0., Px=0., Py=0., Pz=0.;
258 std::vector<double>dm2dphi(NTrk), dm2dtheta(NTrk), dm2dqOverP(NTrk);
260 for(
unsigned int it=0; it<NTrk; it++) {
261 if (masses[it] >= 0.) {
264 V0_cor(5*it+2,5*it+2) = (*cov_tmp)(2,2);
265 V0_cor(5*it+2,5*it+3) = (*cov_tmp)(2,3);
266 V0_cor(5*it+2,5*it+4) = (*cov_tmp)(2,4);
267 V0_cor(5*it+3,5*it+3) = (*cov_tmp)(3,3);
268 V0_cor(5*it+3,5*it+4) = (*cov_tmp)(3,4);
269 V0_cor(5*it+4,5*it+4) = (*cov_tmp)(4,4);
270 V0_cor(5*it+3,5*it+2) = (*cov_tmp)(2,3);
271 V0_cor(5*it+4,5*it+2) = (*cov_tmp)(2,4);
272 V0_cor(5*it+4,5*it+3) = (*cov_tmp)(3,4);
273 double trkCharge = 1.;
274 if (bPer->parameters()(
Trk::qOverP) < 0.) trkCharge = -1.;
279 double tmp = 1./(
qOverP[it]*
qOverP[it]) + masses[it]*masses[it];
280 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
288 double msq = E*E - Px*Px - Py*Py - Pz*Pz;
289 double mass = (msq>0.) ? sqrt(msq) : 0.;
291 for(
unsigned int it=0; it<NTrk; it++) {
292 if (masses[it] >= 0.) {
300 for(
unsigned int it=0; it<NTrk; it++) {
301 D_vec(5*it+0,0) = 0.;
302 D_vec(5*it+1,0) = 0.;
303 D_vec(5*it+2,0) = dm2dphi[it];
304 D_vec(5*it+3,0) = dm2dtheta[it];
305 D_vec(5*it+4,0) = dm2dqOverP[it];
308 Amg::MatrixX V0_merr = D_vec.transpose() * V0_cor * D_vec;
310 double massVarsq = V0_merr(0,0);
311 if (massVarsq <= 0.)
ATH_MSG_DEBUG(
"massError: negative sqrt massVarsq " << massVarsq);
312 double massVar = (massVarsq>0.) ? sqrt(massVarsq) : 0.;
313 double massErr = massVar/(2.*mass);
319 std::array<double, 2> masses = {posTrackMass , negTrackMass};
330 double chi2 = (V0Mass - mass)*(V0Mass - mass)/(massErr*massErr);
332 Genfun::CumulativeChiSquare myCumulativeChiSquare(ndf);
334 double achi2prob = 1.-myCumulativeChiSquare(
chi2);
350 double chi2 = (V0Mass - mass)*(V0Mass - mass)/(massErr*massErr);
352 Genfun::CumulativeChiSquare myCumulativeChiSquare(ndf);
354 double achi2prob = 1.-myCumulativeChiSquare(
chi2);
376 if (NTrk != 2)
return mom;
377 for(
unsigned int it=0; it<NTrk; it++) {
388 if (NTrk != 2)
return mom;
389 for(
unsigned int it=0; it<NTrk; it++) {
400 for(
unsigned int it=0; it<NTrk; it++) {
410 double tmp = mass*mass + mom.x()*mom.x() + mom.y()*mom.y() + mom.z()*mom.z();
411 double e = (tmp>0.) ? sqrt(tmp) : 0.;
412 lorentz.SetPxPyPzE(mom.x(), mom.y(), mom.z(), e);
420 double tmp = mass*mass + mom.x()*mom.x() + mom.y()*mom.y() + mom.z()*mom.z();
421 double e = (tmp>0.) ? sqrt(tmp) : 0.;
422 lorentz.SetPxPyPzE(mom.x(), mom.y(), mom.z(), e);
430 double tmp = mass*mass + mom.x()*mom.x() + mom.y()*mom.y() + mom.z()*mom.z();
431 double e = (tmp>0.) ? sqrt(tmp) : 0.;
432 lorentz.SetPxPyPzE(mom.x(), mom.y(), mom.z(), e);
439 double tmp = V0Mass*V0Mass + mom.x()*mom.x() + mom.y()*mom.y() + mom.z()*mom.z();
440 double e = (tmp>0.) ? sqrt(tmp) : 0.;
442 lorentz.SetPxPyPzE(mom.x(), mom.y(), mom.z(), e);
458 float dof =
ndof(vxCandidate);
460 Genfun::CumulativeChiSquare myCumulativeChiSquare(dof);
461 float chi =
chisq(vxCandidate);
463 double chi2prob = 1.-myCumulativeChiSquare(chi);
483 return vxCandidate->
position().perp();
498 double rxysq = dx*dx + dy*dy;
499 double rxy = (rxysq>0.) ? sqrt(rxysq) : 0.;
500 double drdx = dx/
rxy;
501 double drdy = dy/
rxy;
505 Amg::MatrixX rxy_err = D_vec.transpose() * cov.block<2,2>(0,0) * D_vec;
506 double rxyVar = rxy_err(0,0);
512 const Amg::MatrixX& cov = vxCandidate->covariancePosition();
513 double dx = vxCandidate->
position().x();
514 double dy = vxCandidate->
position().y();
515 double rxyVar =
rxy_var(dx,dy,cov);
516 if (rxyVar <= 0.)
ATH_MSG_DEBUG(
"rxyError: negative sqrt rxyVar " << rxyVar);
517 return (rxyVar>0.) ? sqrt(rxyVar) : 0.;
522 const Amg::MatrixX cov = vxCandidate->covariancePosition() +
vertex->covariancePosition();
524 double dx = vert.x();
525 double dy = vert.y();
526 double rxyVar =
rxy_var(dx,dy,cov);
527 if (rxyVar <= 0.)
ATH_MSG_DEBUG(
"rxyError: negative sqrt rxyVar " << rxyVar);
528 return (rxyVar>0.) ? sqrt(rxyVar) : 0.;
533 const Amg::MatrixX& cov = vxCandidate->covariancePosition();
535 double dx = vert.x();
536 double dy = vert.y();
537 double rxyVar =
rxy_var(dx,dy,cov);
538 if (rxyVar <= 0.)
ATH_MSG_DEBUG(
"rxyError: negative sqrt rxyVar " << rxyVar);
539 return (rxyVar>0.) ? sqrt(rxyVar) : 0.;
551 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
552 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
553 std::vector<double>dPTdqOverP(NTrk), dPTdtheta(NTrk), dPTdphi(NTrk);
556 for(
unsigned int it=0; it<NTrk; it++) {
558 double trkCharge = 1.;
559 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
572 double PTsq = Px*Px+Py*Py;
573 double PT = (PTsq>0.) ? sqrt(PTsq) : 0.;
575 for(
unsigned int it=0; it<NTrk; it++) {
576 dPTdqOverP[it] = (Px*dpxdqOverP[it]+Py*dpydqOverP[it])/PT;
577 dPTdtheta[it] = (Px*dpxdtheta[it]+Py*dpydtheta[it])/PT;
578 dPTdphi[it] = (Px*dpxdphi[it]+Py*dpydphi[it])/PT;
581 unsigned int ndim = 0;
582 if (fullCov.size() == 0) {
585 ndim = fullCov.rows();
589 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
591 for(
unsigned int it=0; it<NTrk; it++) {
592 D_vec(5*it+0,0) = 0.;
593 D_vec(5*it+1,0) = 0.;
594 D_vec(5*it+2,0) = dPTdphi[it];
595 D_vec(5*it+3,0) = dPTdtheta[it];
596 D_vec(5*it+4,0) = dPTdqOverP[it];
598 if (fullCov.size() == 0) {
600 PtErrSq = D_vec.transpose() * V0_cov * D_vec;
602 PtErrSq = D_vec.transpose() * fullCov.block(0,0,5*NTrk, 5*NTrk) * D_vec;
604 }
else if (ndim == 3*NTrk+3) {
606 for(
unsigned int it=0; it<NTrk; it++) {
607 D_vec(3*it+0,0) = dPTdphi[it];
608 D_vec(3*it+1,0) = dPTdtheta[it];
609 D_vec(3*it+2,0) = dPTdqOverP[it];
611 PtErrSq = D_vec.transpose() * fullCov.block(3,3,3*NTrk,3*NTrk) * D_vec;
617 double PtErrsq = PtErrSq(0,0);
618 if (PtErrsq <= 0.)
ATH_MSG_DEBUG(
"ptError: negative sqrt PtErrsq " << PtErrsq);
619 return (PtErrsq>0.) ? sqrt(PtErrsq) : 0.;
624 assert(vxCandidate!=0);
625 if(
nullptr == vxCandidate) {
632 double p2 =
P.mag2();
633 double pdr =
P.dot((sv - pv));
634 return sv -
P*pdr/p2;
639 const Amg::MatrixX& cov = (vxCandidate->covariancePosition() +
vertex->covariancePosition()).inverse().eval();
645 Amg::MatrixX sepVarsqMat = D_vec.transpose() * cov * D_vec;
646 double sepVarsq = sepVarsqMat(0,0);
647 if (sepVarsq <= 0.)
ATH_MSG_DEBUG(
"separation: negative sqrt sepVarsq " << sepVarsq);
648 double sepVar = (sepVarsq>0.) ? sqrt(sepVarsq) : 0.;
654 const Amg::SymMatrixX& cov = vxCandidate->covariancePosition().inverse().eval();
660 Amg::MatrixX sepVarsqMat = D_vec.transpose() * cov * D_vec;
661 double sepVarsq = sepVarsqMat(0,0);
662 if (sepVarsq <= 0.)
ATH_MSG_DEBUG(
"separation: negative sqrt sepVarsq " << sepVarsq);
663 double sepVar = (sepVarsq>0.) ? sqrt(sepVarsq) : 0.;
670 double sinTheta_xy = ((1.-cosineTheta_xy*cosineTheta_xy)>0.) ? sqrt((1.-cosineTheta_xy*cosineTheta_xy)) : 0.;
671 return (
vtx(vxCandidate)-
vertex->position()).perp() * sinTheta_xy;
686 double sinTheta = ((1.-cosineTheta*cosineTheta)>0.) ? sqrt((1.-cosineTheta*cosineTheta)) : 0.;
687 return (
vtx(vxCandidate)-
vertex->position()).mag() * sinTheta;
695 double dx = vert.x();
696 double dy = vert.y();
697 double dz = vert.z();
698 double Px=0., Py=0., Pz=0.;
699 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
700 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
701 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk);
702 std::vector<double>da0dqOverP(NTrk), da0dtheta(NTrk), da0dphi(NTrk);
705 for(
unsigned int it=0; it<NTrk; it++) {
707 double trkCharge = 1.;
708 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
724 double P2 = Px*Px+Py*Py+Pz*Pz;
725 double B = Px*dx+Py*dy+Pz*dz;
727 double da0dx = (Px*Pz)/P2;
728 double da0dy = (Py*Pz)/P2;
729 double da0dz = (Pz*Pz)/P2 - 1.;
730 double da0dx0 = -da0dx;
731 double da0dy0 = -da0dy;
732 double da0dz0 = -da0dz;
733 for(
unsigned int it=0; it<NTrk; it++) {
734 double dP2dqOverP = 2.*(Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it]);
735 double dP2dtheta = 2.*(Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it]);
736 double dP2dphi = 2.*(Px*dpxdphi[it]+Py*dpydphi[it]);
737 da0dqOverP[it] = (B*(P2*dpzdqOverP[it]-Pz*dP2dqOverP) +
738 Pz*P2*(dx*dpxdqOverP[it]+dy*dpydqOverP[it]+dz*dpzdqOverP[it]))/(P2*P2);
739 da0dtheta[it] = (B*(P2*dpzdtheta[it]-Pz*dP2dtheta) +
740 Pz*P2*(dx*dpxdtheta[it]+dy*dpydtheta[it]+dz*dpzdtheta[it]))/(P2*P2);
741 da0dphi[it] = -(B*Pz*dP2dphi -
742 Pz*P2*(dx*dpxdphi[it]+dy*dpydphi[it]))/(P2*P2);
745 unsigned int ndim = 0;
746 if (fullCov.size() != 0) {
747 ndim = fullCov.rows();
753 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
755 for(
unsigned int it=0; it<NTrk; it++) {
758 D_vec(5*it+2) = da0dphi[it];
759 D_vec(5*it+3) = da0dtheta[it];
760 D_vec(5*it+4) = da0dqOverP[it];
762 D_vec(5*NTrk+0) = da0dx;
763 D_vec(5*NTrk+1) = da0dy;
764 D_vec(5*NTrk+2) = da0dz;
765 D_vec(5*NTrk+3) = da0dx0;
766 D_vec(5*NTrk+4) = da0dy0;
767 D_vec(5*NTrk+5) = da0dz0;
770 if (fullCov.size() != 0) {
771 W_mat.block(0,0,ndim,ndim) = fullCov;
774 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
775 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
777 W_mat.block<3,3>(5*NTrk+3,5*NTrk+3) =
vertex->covariancePosition();
778 V0_err = D_vec.transpose() * W_mat * D_vec;
779 }
else if (ndim == 3*NTrk+3) {
784 for(
unsigned int it=0; it<NTrk; it++) {
785 D_vec(3*it+3) = da0dphi[it];
786 D_vec(3*it+4) = da0dtheta[it];
787 D_vec(3*it+5) = da0dqOverP[it];
789 D_vec(3*NTrk+3) = da0dx0;
790 D_vec(3*NTrk+4) = da0dy0;
791 D_vec(3*NTrk+5) = da0dz0;
794 W_mat.block(0,0,ndim,ndim) = fullCov;
795 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
796 V0_err = D_vec.transpose() * W_mat * D_vec;
802 double a0Errsq = V0_err(0,0);
803 if (a0Errsq <= 0.)
ATH_MSG_DEBUG(
"a0Error: negative sqrt a0Errsq " << a0Errsq);
804 double a0Err = (a0Errsq>0.) ? sqrt(a0Errsq) : 0.;
817 double dx = vert.x();
818 double dy = vert.y();
819 double dz = vert.z();
820 double Px=0., Py=0., Pz=0.;
821 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
822 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
823 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk);
824 std::vector<double>da0dqOverP(NTrk), da0dtheta(NTrk), da0dphi(NTrk);
827 for(
unsigned int it=0; it<NTrk; it++) {
829 double trkCharge = 1.;
830 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
859 double P = sqrt(Px*Px+Py*Py+Pz*Pz);
860 double r = sqrt(dx*dx+dy*dy+dz*dz);
862 double da0dx = (Px/
P*
r*cosineTheta - dx)/a0val;
863 double da0dy = (Py/
P*
r*cosineTheta - dy)/a0val;
864 double da0dz = (Pz/
P*
r*cosineTheta - dz)/a0val;
865 double da0dx0 = -da0dx;
866 double da0dy0 = -da0dy;
867 double da0dz0 = -da0dz;
868 for(
unsigned int it=0; it<NTrk; it++) {
869 da0dqOverP[it] = -(
r*cosineTheta/
P)*(da0dx*dpxdqOverP[it]+da0dy*dpydqOverP[it]+da0dz*dpzdqOverP[it]);
870 da0dtheta[it] = -(
r*cosineTheta/
P)*(da0dx*dpxdtheta[it]+da0dy*dpydtheta[it]+da0dz*dpzdtheta[it]);
871 da0dphi[it] = -(
r*cosineTheta/
P)*(da0dx*dpxdphi[it]+da0dy*dpydphi[it]);
874 unsigned int ndim = 0;
875 if (fullCov.size() != 0) {
876 ndim = fullCov.rows();
882 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
884 for(
unsigned int it=0; it<NTrk; it++) {
887 D_vec(5*it+2) = da0dphi[it];
888 D_vec(5*it+3) = da0dtheta[it];
889 D_vec(5*it+4) = da0dqOverP[it];
891 D_vec(5*NTrk+0) = da0dx;
892 D_vec(5*NTrk+1) = da0dy;
893 D_vec(5*NTrk+2) = da0dz;
894 D_vec(5*NTrk+3) = da0dx0;
895 D_vec(5*NTrk+4) = da0dy0;
896 D_vec(5*NTrk+5) = da0dz0;
899 if (fullCov.size() != 0) {
900 W_mat.block(0,0,ndim,ndim) = fullCov;
903 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
904 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
906 W_mat.block<3,3>(5*NTrk+3,5*NTrk+3) =
vertex->covariancePosition();
907 V0_err = D_vec.transpose() * W_mat * D_vec;
908 }
else if (ndim == 3*NTrk+3) {
913 for(
unsigned int it=0; it<NTrk; it++) {
914 D_vec(3*it+3) = da0dphi[it];
915 D_vec(3*it+4) = da0dtheta[it];
916 D_vec(3*it+5) = da0dqOverP[it];
918 D_vec(3*NTrk+3) = da0dx0;
919 D_vec(3*NTrk+4) = da0dy0;
920 D_vec(3*NTrk+5) = da0dz0;
923 W_mat.block(0,0,ndim,ndim) = fullCov;
924 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
925 V0_err = D_vec.transpose() * W_mat * D_vec;
931 double a0Errsq = V0_err(0,0);
932 if (a0Errsq <= 0.)
ATH_MSG_DEBUG(
"a0Error: negative sqrt a0Errsq " << a0Errsq);
933 double a0Err = (a0Errsq>0.) ? sqrt(a0Errsq) : 0.;
940 double dx = vert.x();
941 double dy = vert.y();
943 double dxy = (mom.x()*dx + mom.y()*dy)/mom.perp();
950 double dx = vert.x();
951 double dy = vert.y();
954 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
955 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
956 std::vector<double>dLxydqOverP(NTrk), dLxydtheta(NTrk), dLxydphi(NTrk);
959 for(
unsigned int it=0; it<NTrk; it++) {
961 double trkCharge = 1.;
962 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
975 double PTsq = Px*Px+Py*Py;
976 double PT = (PTsq>0.) ? sqrt(PTsq) : 0.;
977 double LXYoverPT = (Px*dx+Py*dy)/PTsq;
979 for(
unsigned int it=0; it<NTrk; it++) {
980 double dPTdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it])/PT;
981 double dPTdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it])/PT;
982 double dPTdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/PT;
983 dLxydqOverP[it] = (dx*dpxdqOverP[it]+dy*dpydqOverP[it])/PT-LXYoverPT*dPTdqOverP;
984 dLxydtheta[it] = (dx*dpxdtheta[it]+dy*dpydtheta[it])/PT-LXYoverPT*dPTdtheta;
985 dLxydphi[it] = (dx*dpxdphi[it]+dy*dpydphi[it])/PT-LXYoverPT*dPTdphi;
987 double dLxydx = Px/PT;
988 double dLxydy = Py/PT;
989 double dLxydx0 = -dLxydx;
990 double dLxydy0 = -dLxydy;
992 unsigned int ndim = 0;
993 if (fullCov.size() != 0) {
994 ndim = fullCov.rows();
1000 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
1002 for(
unsigned int it=0; it<NTrk; it++) {
1005 D_vec(5*it+2) = dLxydphi[it];
1006 D_vec(5*it+3) = dLxydtheta[it];
1007 D_vec(5*it+4) = dLxydqOverP[it];
1009 D_vec(5*NTrk+0) = dLxydx;
1010 D_vec(5*NTrk+1) = dLxydy;
1011 D_vec(5*NTrk+2) = 0.;
1012 D_vec(5*NTrk+3) = dLxydx0;
1013 D_vec(5*NTrk+4) = dLxydy0;
1014 D_vec(5*NTrk+5) = 0.;
1016 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
1017 if (fullCov.size() != 0) {
1018 W_mat.block(0,0,ndim,ndim) = fullCov;
1021 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
1022 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
1024 W_mat.block<3,3>(5*NTrk+3,5*NTrk+3) =
vertex->covariancePosition();
1025 V0_err = D_vec.transpose() * W_mat * D_vec;
1026 }
else if (ndim == 3*NTrk+3) {
1031 for(
unsigned int it=0; it<NTrk; it++) {
1032 D_vec(3*it+3) = dLxydphi[it];
1033 D_vec(3*it+4) = dLxydtheta[it];
1034 D_vec(3*it+5) = dLxydqOverP[it];
1036 D_vec(3*NTrk+3) = dLxydx0;
1037 D_vec(3*NTrk+4) = dLxydy0;
1038 D_vec(3*NTrk+5) = 0.;
1040 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
1041 W_mat.block(0,0,ndim,ndim) = fullCov;
1042 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
1043 V0_err = D_vec.transpose() * W_mat * D_vec;
1049 double LxyErrsq = V0_err(0,0);
1050 if (LxyErrsq <= 0.)
ATH_MSG_DEBUG(
"lxyError: negative sqrt LxyErrsq " << LxyErrsq);
1051 return (LxyErrsq>0.) ? sqrt(LxyErrsq) : 0.;
1057 double dx = vert.x();
1058 double dy = vert.y();
1059 double dz = vert.z();
1061 double dxyz= (mom.x()*dx + mom.y()*dy + mom.z()*dz)/mom.mag();
1068 double dx = vert.x();
1069 double dy = vert.y();
1070 double dz = vert.z();
1072 double Px=0., Py=0., Pz=0.;
1073 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
1074 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
1075 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk);
1076 std::vector<double>dLxyzdqOverP(NTrk), dLxyzdtheta(NTrk), dLxyzdphi(NTrk);
1079 for(
unsigned int it=0; it<NTrk; it++) {
1081 double trkCharge = 1.;
1082 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
1098 double Psq = Px*Px+Py*Py+Pz*Pz;
1099 double P = (Psq>0.) ? sqrt(Psq) : 0.;
1100 double LXYZoverP = (Px*dx+Py*dy+Pz*dz)/Psq;
1102 for(
unsigned int it=0; it<NTrk; it++) {
1103 double dPdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it])/
P;
1104 double dPdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/
P;
1105 double dPdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/
P;
1106 dLxyzdqOverP[it] = (dx*dpxdqOverP[it]+dy*dpydqOverP[it]+dz*dpzdqOverP[it])/
P-LXYZoverP*dPdqOverP;
1107 dLxyzdtheta[it] = (dx*dpxdtheta[it]+dy*dpydtheta[it]+dz*dpzdtheta[it])/
P-LXYZoverP*dPdtheta;
1108 dLxyzdphi[it] = (dx*dpxdphi[it]+dy*dpydphi[it])/
P-LXYZoverP*dPdphi;
1110 double dLxyzdx = Px/
P;
1111 double dLxyzdy = Py/
P;
1112 double dLxyzdz = Pz/
P;
1113 double dLxyzdx0 = -dLxyzdx;
1114 double dLxyzdy0 = -dLxyzdy;
1115 double dLxyzdz0 = -dLxyzdz;
1117 unsigned int ndim = 0;
1118 if (fullCov.size() != 0) {
1119 ndim = fullCov.rows();
1125 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
1127 for(
unsigned int it=0; it<NTrk; it++) {
1130 D_vec(5*it+2) = dLxyzdphi[it];
1131 D_vec(5*it+3) = dLxyzdtheta[it];
1132 D_vec(5*it+4) = dLxyzdqOverP[it];
1134 D_vec(5*NTrk+0) = dLxyzdx;
1135 D_vec(5*NTrk+1) = dLxyzdy;
1136 D_vec(5*NTrk+2) = dLxyzdz;
1137 D_vec(5*NTrk+3) = dLxyzdx0;
1138 D_vec(5*NTrk+4) = dLxyzdy0;
1139 D_vec(5*NTrk+5) = dLxyzdz0;
1141 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
1142 if (fullCov.size() != 0) {
1143 W_mat.block(0,0,ndim,ndim) = fullCov;
1146 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
1147 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
1149 W_mat.block<3,3>(5*NTrk+3,5*NTrk+3) =
vertex->covariancePosition();
1150 V0_err = D_vec.transpose() * W_mat * D_vec;
1151 }
else if (ndim == 3*NTrk+3) {
1156 for(
unsigned int it=0; it<NTrk; it++) {
1157 D_vec(3*it+3) = dLxyzdphi[it];
1158 D_vec(3*it+4) = dLxyzdtheta[it];
1159 D_vec(3*it+5) = dLxyzdqOverP[it];
1161 D_vec(3*NTrk+3) = dLxyzdx0;
1162 D_vec(3*NTrk+4) = dLxyzdy0;
1163 D_vec(3*NTrk+5) = dLxyzdz0;
1165 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
1166 W_mat.block(0,0,ndim,ndim) = fullCov;
1167 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
1168 V0_err = D_vec.transpose() * W_mat * D_vec;
1174 double LxyzErrsq = V0_err(0,0);
1175 if (LxyzErrsq <= 0.)
ATH_MSG_DEBUG(
"lxyzError: negative sqrt LxyzErrsq " << LxyzErrsq);
1176 return (LxyzErrsq>0.) ? sqrt(LxyzErrsq) : 0.;
1181 std::array<double, 2> masses = {posTrackMass, negTrackMass};
1189 if (masses.size() != NTrk) {
1190 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
1194 double CONST = 1000./299.792;
1198 return CONST*M*LXY/PT;
1203 std::array<double, 2> masses = {posTrackMass, negTrackMass};
1205 return tau(vxCandidate,
vertex,masses,massV0);
1211 if (masses.size() != NTrk) {
1212 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
1218 double descr = cov(0,0)*cov(1,1)-cov(0,1)*cov(0,1);
1219 double cov_i11 = cov(1,1)/descr;
1220 double cov_i12 = -cov(0,1)/descr;
1221 double deltaTau = -(massV0-mass)*cov_i12/cov_i11;
1222 return Tau + deltaTau;
1228 double CONST = 1000./299.792;
1231 return CONST*M*LXY/PT;
1237 std::array<double, 2> masses = {posTrackMass, negTrackMass};
1246 if (masses.size() != NTrk) {
1247 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
1251 double CONST = 1000./299.792;
1254 double dx = vert.x();
1255 double dy = vert.y();
1257 double E=0., Px=0., Py=0., Pz=0.;
1258 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
1259 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
1260 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk), dedqOverP(NTrk);
1261 std::vector<double>dTaudqOverP(NTrk), dTaudtheta(NTrk), dTaudphi(NTrk);
1264 for(
unsigned int it=0; it<NTrk; it++) {
1266 double trkCharge = 1.;
1267 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
1271 double tmp = 1./(
qOverP*
qOverP) + masses[it]*masses[it];
1272 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
1287 double LXY = Px*dx+Py*dy;
1289 for(
unsigned int it=0; it<NTrk; it++) {
1290 double dMdqOverP = -(Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it]-E*dedqOverP[it])/M;
1291 double dMdtheta = -(Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/M;
1292 double dMdphi = -(Px*dpxdphi[it]+Py*dpydphi[it])/M;
1293 double dPTdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it])/PT;
1294 double dPTdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it])/PT;
1295 double dPTdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/PT;
1296 double dLXYdqOverP = dx*dpxdqOverP[it]+dy*dpydqOverP[it];
1297 double dLXYdtheta = dx*dpxdtheta[it]+dy*dpydtheta[it];
1298 double dLXYdphi = dx*dpxdphi[it]+dy*dpydphi[it];
1299 dTaudqOverP[it] = (LXY*dMdqOverP+M*dLXYdqOverP)/(PT*PT)-(2.*LXY*M*dPTdqOverP)/(PT*PT*PT);
1300 dTaudtheta[it] = (LXY*dMdtheta+M*dLXYdtheta)/(PT*PT)-(2.*LXY*M*dPTdtheta)/(PT*PT*PT);
1301 dTaudphi[it] = (LXY*dMdphi+M*dLXYdphi)/(PT*PT)-(2.*LXY*M*dPTdphi)/(PT*PT*PT);
1303 double dTaudx = (M*Px)/(PT*PT);
1304 double dTaudy = (M*Py)/(PT*PT);
1305 double dTaudx0 = -dTaudx;
1306 double dTaudy0 = -dTaudy;
1308 unsigned int ndim = 0;
1309 if (fullCov.size() != 0) {
1310 ndim = fullCov.rows();
1316 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
1318 for(
unsigned int it=0; it<NTrk; it++) {
1321 D_vec(5*it+2) = dTaudphi[it];
1322 D_vec(5*it+3) = dTaudtheta[it];
1323 D_vec(5*it+4) = dTaudqOverP[it];
1325 D_vec(5*NTrk+0) = dTaudx;
1326 D_vec(5*NTrk+1) = dTaudy;
1327 D_vec(5*NTrk+2) = 0.;
1328 D_vec(5*NTrk+3) = dTaudx0;
1329 D_vec(5*NTrk+4) = dTaudy0;
1330 D_vec(5*NTrk+5) = 0.;
1332 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
1333 if (fullCov.size() != 0) {
1334 W_mat.block(0,0,ndim,ndim) = fullCov;
1337 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
1338 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
1340 W_mat.block<3,3>(5*NTrk+3,5*NTrk+3) =
vertex->covariancePosition();
1341 V0_err = D_vec.transpose() * W_mat * D_vec;
1342 }
else if (ndim == 3*NTrk+3) {
1347 for(
unsigned int it=0; it<NTrk; it++) {
1348 D_vec(3*it+3) = dTaudphi[it];
1349 D_vec(3*it+4) = dTaudtheta[it];
1350 D_vec(3*it+5) = dTaudqOverP[it];
1352 D_vec(3*NTrk+3) = dTaudx0;
1353 D_vec(3*NTrk+4) = dTaudy0;
1354 D_vec(3*NTrk+5) = 0.;
1356 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
1357 W_mat.block(0,0,ndim,ndim) = fullCov;
1358 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
1359 V0_err = D_vec.transpose() * W_mat * D_vec;
1365 double tauErrsq = V0_err(0,0);
1366 if (tauErrsq <= 0.)
ATH_MSG_DEBUG(
"tauError: negative sqrt tauErrsq " << tauErrsq);
1367 double tauErr = (tauErrsq>0.) ? sqrt(tauErrsq) : 0.;
1368 return CONST*tauErr;
1373 std::array<double, 2> masses = {posTrackMass, negTrackMass};
1381 if (masses.size() != NTrk) {
1382 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
1385 double error = -999999.;
1387 double descr = cov(0,0)*cov(1,1)-cov(0,1)*cov(0,1);
1388 double cov_i11 = cov(1,1)/descr;
1389 if (cov_i11 > 0.)
error = 1./sqrt(cov_i11);
1397 double CONST = 1000./299.792;
1400 double dx = vecsub.x();
1401 double dy = vecsub.y();
1403 double Px=0., Py=0.;
1404 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
1405 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
1406 std::vector<double>dPTdtheta(NTrk), dPTdphi(NTrk);
1407 std::vector<double>dTaudqOverP(NTrk), dTaudtheta(NTrk), dTaudphi(NTrk);
1410 for(
unsigned int it=0; it<NTrk; it++) {
1412 double trkCharge = 1.;
1413 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
1426 double LXY = Px*dx+Py*dy;
1428 for(
unsigned int it=0; it<NTrk; it++) {
1429 double dPTdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it])/PT;
1430 double dPTdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it])/PT;
1431 double dPTdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/PT;
1432 double dLXYdqOverP = dx*dpxdqOverP[it]+dy*dpydqOverP[it];
1433 double dLXYdtheta = dx*dpxdtheta[it]+dy*dpydtheta[it];
1434 double dLXYdphi = dx*dpxdphi[it]+dy*dpydphi[it];
1435 dTaudqOverP[it] = M*dLXYdqOverP/(PT*PT)-(2.*LXY*M*dPTdqOverP)/(PT*PT*PT);
1436 dTaudtheta[it] = M*dLXYdtheta/(PT*PT)-(2.*LXY*M*dPTdtheta)/(PT*PT*PT);
1437 dTaudphi[it] = M*dLXYdphi/(PT*PT)-(2.*LXY*M*dPTdphi)/(PT*PT*PT);
1439 double dTaudx = (M*Px)/(PT*PT);
1440 double dTaudy = (M*Py)/(PT*PT);
1441 double dTaudx0 = -dTaudx;
1442 double dTaudy0 = -dTaudy;
1444 unsigned int ndim = 0;
1445 if (fullCov.size() != 0) {
1446 ndim = fullCov.rows();
1452 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
1454 for(
unsigned int it=0; it<NTrk; it++) {
1457 D_vec(5*it+2) = dTaudphi[it];
1458 D_vec(5*it+3) = dTaudtheta[it];
1459 D_vec(5*it+4) = dTaudqOverP[it];
1461 D_vec(5*NTrk+0) = dTaudx;
1462 D_vec(5*NTrk+1) = dTaudy;
1463 D_vec(5*NTrk+2) = 0.;
1464 D_vec(5*NTrk+3) = dTaudx0;
1465 D_vec(5*NTrk+4) = dTaudy0;
1466 D_vec(5*NTrk+5) = 0.;
1468 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
1469 if (fullCov.size() != 0) {
1470 W_mat.block(0,0,ndim,ndim) = fullCov;
1473 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
1474 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
1476 W_mat.block<3,3>(5*NTrk+3,5*NTrk+3) =
vertex->covariancePosition();
1477 V0_err = D_vec.transpose() * W_mat * D_vec;
1478 }
else if (ndim == 3*NTrk+3) {
1483 for(
unsigned int it=0; it<NTrk; it++) {
1484 D_vec(3*it+3) = dTaudphi[it];
1485 D_vec(3*it+4) = dTaudtheta[it];
1486 D_vec(3*it+5) = dTaudqOverP[it];
1488 D_vec(3*NTrk+3) = dTaudx0;
1489 D_vec(3*NTrk+4) = dTaudy0;
1490 D_vec(3*NTrk+5) = 0.;
1492 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
1493 W_mat.block(0,0,ndim,ndim) = fullCov;
1494 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
1495 V0_err = D_vec.transpose() * W_mat * D_vec;
1501 double tauErrsq = V0_err(0,0);
1502 if (tauErrsq <= 0.)
ATH_MSG_DEBUG(
"tauError: negative sqrt tauErrsq " << tauErrsq);
1503 double tauErr = (tauErrsq>0.) ? sqrt(tauErrsq) : 0.;
1504 return CONST*tauErr;
1510 if (masses.size() != NTrk) {
1511 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
1515 double CONST = 1000./299.792;
1519 return CONST*M*LXYZ/
P;
1525 double CONST = 1000./299.792;
1528 return CONST*M*LXYZ/
P;
1535 if (masses.size() != NTrk) {
1536 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
1540 double CONST = 1000./299.792;
1543 double dx = vert.x();
1544 double dy = vert.y();
1545 double dz = vert.z();
1547 double E=0., Px=0., Py=0., Pz=0.;
1548 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
1549 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
1550 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk), dedqOverP(NTrk);
1551 std::vector<double>dTaudqOverP(NTrk), dTaudtheta(NTrk), dTaudphi(NTrk);
1554 for(
unsigned int it=0; it<NTrk; it++) {
1556 double trkCharge = 1.;
1557 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
1561 double tmp = 1./(
qOverP*
qOverP) + masses[it]*masses[it];
1562 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
1577 double LXYZ = Px*dx+Py*dy+Pz*dz;
1579 for(
unsigned int it=0; it<NTrk; it++) {
1580 double dMdqOverP = -(Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it]-E*dedqOverP[it])/M;
1581 double dMdtheta = -(Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/M;
1582 double dMdphi = -(Px*dpxdphi[it]+Py*dpydphi[it])/M;
1583 double dPdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it])/
P;
1584 double dPdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/
P;
1585 double dPdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/
P;
1586 double dLXYZdqOverP = dx*dpxdqOverP[it]+dy*dpydqOverP[it]+dz*dpzdqOverP[it];
1587 double dLXYZdtheta = dx*dpxdtheta[it]+dy*dpydtheta[it]+dz*dpzdtheta[it];
1588 double dLXYZdphi = dx*dpxdphi[it]+dy*dpydphi[it];
1589 dTaudqOverP[it] = (LXYZ*dMdqOverP+M*dLXYZdqOverP)/(
P*
P)-(2.*LXYZ*M*dPdqOverP)/(
P*
P*
P);
1590 dTaudtheta[it] = (LXYZ*dMdtheta+M*dLXYZdtheta)/(
P*
P)-(2.*LXYZ*M*dPdtheta)/(
P*
P*
P);
1591 dTaudphi[it] = (LXYZ*dMdphi+M*dLXYZdphi)/(
P*
P)-(2.*LXYZ*M*dPdphi)/(
P*
P*
P);
1593 double dTaudx = (M*Px)/(
P*
P);
1594 double dTaudy = (M*Py)/(
P*
P);
1595 double dTaudz = (M*Pz)/(
P*
P);
1596 double dTaudx0 = -dTaudx;
1597 double dTaudy0 = -dTaudy;
1598 double dTaudz0 = -dTaudz;
1600 unsigned int ndim = 0;
1601 if (fullCov.size() != 0) {
1602 ndim = fullCov.rows();
1608 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
1610 for(
unsigned int it=0; it<NTrk; it++) {
1613 D_vec(5*it+2) = dTaudphi[it];
1614 D_vec(5*it+3) = dTaudtheta[it];
1615 D_vec(5*it+4) = dTaudqOverP[it];
1617 D_vec(5*NTrk+0) = dTaudx;
1618 D_vec(5*NTrk+1) = dTaudy;
1619 D_vec(5*NTrk+2) = dTaudz;
1620 D_vec(5*NTrk+3) = dTaudx0;
1621 D_vec(5*NTrk+4) = dTaudy0;
1622 D_vec(5*NTrk+5) = dTaudz0;
1624 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
1625 if (fullCov.size() != 0) {
1626 W_mat.block(0,0,ndim,ndim) = fullCov;
1629 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
1630 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
1632 W_mat.block<3,3>(5*NTrk+3,5*NTrk+3) =
vertex->covariancePosition();
1633 V0_err = D_vec.transpose() * W_mat * D_vec;
1634 }
else if (ndim == 3*NTrk+3) {
1639 for(
unsigned int it=0; it<NTrk; it++) {
1640 D_vec(3*it+3) = dTaudphi[it];
1641 D_vec(3*it+4) = dTaudtheta[it];
1642 D_vec(3*it+5) = dTaudqOverP[it];
1644 D_vec(3*NTrk+3) = dTaudx0;
1645 D_vec(3*NTrk+4) = dTaudy0;
1646 D_vec(3*NTrk+5) = dTaudz0;
1648 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
1649 W_mat.block(0,0,ndim,ndim) = fullCov;
1650 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
1651 V0_err = D_vec.transpose() * W_mat * D_vec;
1657 double tauErrsq = V0_err(0,0);
1658 if (tauErrsq <= 0.)
ATH_MSG_DEBUG(
"tauError: negative sqrt tauErrsq " << tauErrsq);
1659 double tauErr = (tauErrsq>0.) ? sqrt(tauErrsq) : 0.;
1660 return CONST*tauErr;
1667 double CONST = 1000./299.792;
1670 double dx = vecsub.x();
1671 double dy = vecsub.y();
1672 double dz = vecsub.z();
1674 double Px=0., Py=0., Pz=0.;
1675 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
1676 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
1677 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk);
1678 std::vector<double>dTaudqOverP(NTrk), dTaudtheta(NTrk), dTaudphi(NTrk);
1681 for(
unsigned int it=0; it<NTrk; it++) {
1683 double trkCharge = 1.;
1684 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
1700 double LXYZ = Px*dx+Py*dy+Pz*dz;
1702 for(
unsigned int it=0; it<NTrk; it++) {
1703 double dPdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it])/
P;
1704 double dPdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/
P;
1705 double dPdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/
P;
1706 double dLXYZdqOverP = dx*dpxdqOverP[it]+dy*dpydqOverP[it]+dz*dpzdqOverP[it];
1707 double dLXYZdtheta = dx*dpxdtheta[it]+dy*dpydtheta[it]+dz*dpzdtheta[it];
1708 double dLXYZdphi = dx*dpxdphi[it]+dy*dpydphi[it];
1709 dTaudqOverP[it] = M*dLXYZdqOverP/(
P*
P)-(2.*LXYZ*M*dPdqOverP)/(
P*
P*
P);
1710 dTaudtheta[it] = M*dLXYZdtheta/(
P*
P)-(2.*LXYZ*M*dPdtheta)/(
P*
P*
P);
1711 dTaudphi[it] = M*dLXYZdphi/(
P*
P)-(2.*LXYZ*M*dPdphi)/(
P*
P*
P);
1713 double dTaudx = (M*Px)/(
P*
P);
1714 double dTaudy = (M*Py)/(
P*
P);
1715 double dTaudz = (M*Pz)/(
P*
P);
1716 double dTaudx0 = -dTaudx;
1717 double dTaudy0 = -dTaudy;
1718 double dTaudz0 = -dTaudz;
1720 unsigned int ndim = 0;
1721 if (fullCov.size() != 0) {
1722 ndim = fullCov.rows();
1728 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
1730 for(
unsigned int it=0; it<NTrk; it++) {
1733 D_vec(5*it+2) = dTaudphi[it];
1734 D_vec(5*it+3) = dTaudtheta[it];
1735 D_vec(5*it+4) = dTaudqOverP[it];
1737 D_vec(5*NTrk+0) = dTaudx;
1738 D_vec(5*NTrk+1) = dTaudy;
1739 D_vec(5*NTrk+2) = dTaudz;
1740 D_vec(5*NTrk+3) = dTaudx0;
1741 D_vec(5*NTrk+4) = dTaudy0;
1742 D_vec(5*NTrk+5) = dTaudz0;
1744 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
1745 if (fullCov.size() != 0) {
1746 W_mat.block(0,0,ndim,ndim) = fullCov;
1749 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
1750 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
1752 W_mat.block<3,3>(5*NTrk+3,5*NTrk+3) =
vertex->covariancePosition();
1753 V0_err = D_vec.transpose() * W_mat * D_vec;
1754 }
else if (ndim == 3*NTrk+3) {
1759 for(
unsigned int it=0; it<NTrk; it++) {
1760 D_vec(3*it+3) = dTaudphi[it];
1761 D_vec(3*it+4) = dTaudtheta[it];
1762 D_vec(3*it+5) = dTaudqOverP[it];
1764 D_vec(3*NTrk+3) = dTaudx0;
1765 D_vec(3*NTrk+4) = dTaudy0;
1766 D_vec(3*NTrk+5) = dTaudz0;
1768 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
1769 W_mat.block(0,0,ndim,ndim) = fullCov;
1770 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
1771 V0_err = D_vec.transpose() * W_mat * D_vec;
1777 double tauErrsq = V0_err(0,0);
1778 if (tauErrsq <= 0.)
ATH_MSG_DEBUG(
"tauError: negative sqrt tauErrsq " << tauErrsq);
1779 double tauErr = (tauErrsq>0.) ? sqrt(tauErrsq) : 0.;
1780 return CONST*tauErr;
1788 CLHEP::HepLorentzVector v1(V1.Px(),V1.Py(),V1.Pz(),V1.E());
1789 CLHEP::HepLorentzVector v2(V2.Px(),V2.Py(),V2.Pz(),V2.E());
1790 CLHEP::HepLorentzVector v0 = v1 + v2;
1791 CLHEP::Hep3Vector boost_v0 = v0.boostVector();
1793 v1.boost( boost_v0 );
1794 v2.boost( boost_v0 );
1795 theta = v0.angle( v1.vect() );
1803 CLHEP::HepLorentzVector posMom(PosMom.Px(),PosMom.Py(),PosMom.Pz(),PosMom.E());
1804 CLHEP::HepLorentzVector negMom(NegMom.Px(),NegMom.Py(),NegMom.Pz(),NegMom.E());
1810 CLHEP::HepLorentzVector v0(posTrack + negTrack);
1811 double Mv0 = v0.m();
1812 double Mplus = posTrack.m();
1813 double Mminus= negTrack.m();
1814 double Pv0 = v0.rho();
1815 double pssq = (Mv0*Mv0-(Mplus+Mminus)*(Mplus+Mminus))*(Mv0*Mv0-(Mplus-Mminus)*(Mplus-Mminus));
1816 double ps = (pssq>0.) ? sqrt(pssq) : 0.;
1818 double pp = v0.px()*posTrack.px() + v0.py()*posTrack.py() + v0.pz()*posTrack.pz();
1819 return ( v0.e()*pp - Pv0*Pv0*posTrack.e())/( Mv0*ps*Pv0);
1827 CLHEP::HepLorentzVector v_pos(V_pos.Px(),V_pos.Py(),V_pos.Pz(),V_pos.E());
1828 CLHEP::HepLorentzVector v_neg(V_neg.Px(),V_neg.Py(),V_neg.Pz(),V_neg.E());
1829 return phiStar(v_pos+v_neg,v_pos);
1832 double V0Tools::phiStar(
const CLHEP::HepLorentzVector & v0,
const CLHEP::HepLorentzVector & track)
1835 CLHEP::Hep3Vector V0 = v0.getV();
1836 CLHEP::Hep3Vector trk = track.getV();
1838 trk.rotateZ(-V0.phi());
1839 trk.rotateY(-V0.theta());
1846 phiStar = atan2(trk.y(),trk.x());
1853 auto vtx1 =
vtx(vxCandidate);
1855 return (mom.dot(vtx1))/(mom.mag()*(vtx1).
mag());
1861 auto vtx1 =
vtx(vxCandidate);
1862 vtx1 -=
vertex->position();
1863 return (mom.dot((vtx1)))/(mom.mag()*(vtx1).
mag());
1869 auto vtx1 =
vtx(vxCandidate);
1871 double pT = mom.perp();
1872 return (mom.x()*vtx1.x()+mom.y()*vtx1.y())/(
pT*vtx1.perp());
1878 auto vtx1 =
vtx(vxCandidate);
1879 vtx1 -=
vertex->position();
1880 double pT = mom.perp();
1881 return (mom.x()*vtx1.x()+mom.y()*vtx1.y())/(
pT*vtx1.perp());
1888 for(
unsigned int it=0; it<NTrk; it++) {
1907 if (NTrk != 2)
return origTrk;
1908 for(
unsigned int it=0; it<NTrk; it++) {
1918 if (NTrk != 2)
return origTrk;
1919 for(
unsigned int it=0; it<NTrk; it++) {
1927 double px = 0.,
py = 0.,
pz = 0., e = 0.;
1929 if (masses.size() != NTrk) {
1930 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
1933 for(
unsigned int it=0; it<NTrk; it++) {
1934 if (masses[it] >= 0.) {
1936 if (TP ==
nullptr)
return -999999.;
1937 TLorentzVector
Tp4 = TP->
p4();
1941 double pesq = 1./(TP->
qOverP()*TP->
qOverP()) + masses[it]*masses[it];
1942 double pe = (pesq>0.) ? sqrt(pesq) : 0.;
1947 return (msq>0.) ? sqrt(msq) : 0.;
1953 double px = 0.,
py = 0.,
pz = 0., e = 0.;
1955 if (masses.size() != NTrk) {
1956 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
1959 for(
unsigned int it=0; it<NTrk; it++) {
1960 if (masses[it] >= 0.) {
1962 if (TP ==
nullptr)
return -999999.;
1963 std::unique_ptr<const Trk::TrackParameters> extrPer =
1965 if (extrPer ==
nullptr)
1967 px += extrPer->momentum().x();
1968 py += extrPer->momentum().y();
1969 pz += extrPer->momentum().z();
1970 double pesq = extrPer->momentum().mag2() + masses[it]*masses[it];
1971 double pe = (pesq>0.) ? sqrt(pesq) : 0.;
1976 return (msq>0.) ? sqrt(msq) : 0.;
1983 double px = 0.,
py = 0.,
pz = 0., e = 0.;
1985 if (masses.size() != NTrk) {
1986 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
1989 for(
unsigned int it=0; it<NTrk; it++) {
1990 if (masses[it] >= 0.) {
1992 if (TP ==
nullptr)
return -999999.;
1993 std::unique_ptr<const Trk::TrackParameters> extrPer =
1995 if (extrPer ==
nullptr)
1997 px += extrPer->momentum().x();
1998 py += extrPer->momentum().y();
1999 pz += extrPer->momentum().z();
2000 double pesq = extrPer->momentum().mag2() + masses[it]*masses[it];
2001 double pe = (pesq>0.) ? sqrt(pesq) : 0.;
2006 return (msq>0.) ? sqrt(msq) : 0.;
2012 if (masses.size() != NTrk) {
2013 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
2017 double E=0., Px=0., Py=0., Pz=0.;
2019 std::vector<double>dm2dphi(NTrk), dm2dtheta(NTrk), dm2dqOverP(NTrk);
2021 for(
unsigned int it=0; it<NTrk; it++) {
2022 if (masses[it] >= 0.) {
2024 if (TP ==
nullptr)
return -999999.;
2026 V0_cor(5*it+2,5*it+2) = cov_tmp(2,2);
2027 V0_cor(5*it+2,5*it+3) = cov_tmp(2,3);
2028 V0_cor(5*it+2,5*it+4) = cov_tmp(2,4);
2029 V0_cor(5*it+3,5*it+3) = cov_tmp(3,3);
2030 V0_cor(5*it+3,5*it+4) = cov_tmp(3,4);
2031 V0_cor(5*it+4,5*it+4) = cov_tmp(4,4);
2032 V0_cor(5*it+3,5*it+2) = cov_tmp(2,3);
2033 V0_cor(5*it+4,5*it+2) = cov_tmp(2,4);
2034 V0_cor(5*it+4,5*it+3) = cov_tmp(3,4);
2039 double tmp = 1./(
qOverP[it]*
qOverP[it]) + masses[it]*masses[it];
2040 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
2043 TLorentzVector p4 = TP->
p4();
2050 for(
unsigned int it=0; it<NTrk; it++) {
2051 if (masses[it] >= 0.) {
2059 for(
unsigned int it=0; it<NTrk; it++) {
2060 D_vec(5*it+0,0) = 0.;
2061 D_vec(5*it+1,0) = 0.;
2062 D_vec(5*it+2,0) = dm2dphi[it];
2063 D_vec(5*it+3,0) = dm2dtheta[it];
2064 D_vec(5*it+4,0) = dm2dqOverP[it];
2066 Amg::MatrixX V0_merr = D_vec.transpose() * V0_cor * D_vec;
2068 double massVarsq = V0_merr(0,0);
2069 if (massVarsq <= 0.)
ATH_MSG_DEBUG(
"massError: negative sqrt massVarsq " << massVarsq);
2070 double massVar = (massVarsq>0.) ? sqrt(massVarsq) : 0.;
2071 double massErr = massVar/(2.*mass);
2079 if (masses.size() != NTrk) {
2080 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
2092 if (masses.size() != NTrk) {
2093 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
2097 double E=0., Px=0., Py=0., Pz=0.;
2099 std::vector<double>dm2dphi(NTrk), dm2dtheta(NTrk), dm2dqOverP(NTrk);
2101 for(
unsigned int it=0; it<NTrk; it++) {
2102 if (masses[it] >= 0.) {
2104 if (TP ==
nullptr)
return -999999.;
2105 std::unique_ptr<const Trk::TrackParameters> extrPer =
2107 if (extrPer ==
nullptr)
2109 const AmgSymMatrix(5)* cov_tmp = extrPer->covariance();
2110 V0_cor(5*it+2,5*it+2) = (*cov_tmp)(2,2);
2111 V0_cor(5*it+2,5*it+3) = (*cov_tmp)(2,3);
2112 V0_cor(5*it+2,5*it+4) = (*cov_tmp)(2,4);
2113 V0_cor(5*it+3,5*it+3) = (*cov_tmp)(3,3);
2114 V0_cor(5*it+3,5*it+4) = (*cov_tmp)(3,4);
2115 V0_cor(5*it+4,5*it+4) = (*cov_tmp)(4,4);
2116 V0_cor(5*it+3,5*it+2) = (*cov_tmp)(2,3);
2117 V0_cor(5*it+4,5*it+2) = (*cov_tmp)(2,4);
2118 V0_cor(5*it+4,5*it+3) = (*cov_tmp)(3,4);
2123 double tmp = 1./(
qOverP[it]*
qOverP[it]) + masses[it]*masses[it];
2124 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
2127 Px += extrPer->momentum().x();
2128 Py += extrPer->momentum().y();
2129 Pz += extrPer->momentum().z();
2132 double msq = E*E - Px*Px - Py*Py - Pz*Pz;
2133 double mass = (msq>0.) ? sqrt(msq) : 0.;
2135 for(
unsigned int it=0; it<NTrk; it++) {
2136 if (masses[it] >= 0.) {
2144 for(
unsigned int it=0; it<NTrk; it++) {
2145 D_vec(5*it+0,0) = 0.;
2146 D_vec(5*it+1,0) = 0.;
2147 D_vec(5*it+2,0) = dm2dphi[it];
2148 D_vec(5*it+3,0) = dm2dtheta[it];
2149 D_vec(5*it+4,0) = dm2dqOverP[it];
2151 Amg::MatrixX V0_merr = D_vec.transpose() * V0_cor * D_vec;
2153 double massVarsq = V0_merr(0,0);
2154 if (massVarsq <= 0.)
ATH_MSG_DEBUG(
"massError: negative sqrt massVarsq " << massVarsq);
2155 double massVar = (massVarsq>0.) ? sqrt(massVarsq) : 0.;
2156 double massErr = massVar/(2.*mass);
2165 if (masses.size() != NTrk) {
2166 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
2170 double CONST = 1000./299.792;
2173 double dx = vert.x();
2174 double dy = vert.y();
2176 double E=0., Px=0., Py=0., Pz=0.;
2177 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
2178 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
2179 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk), dedqOverP(NTrk);
2180 std::vector<double>dMdqOverP(NTrk), dMdtheta(NTrk), dMdphi(NTrk);
2181 std::vector<double>dTaudqOverP(NTrk), dTaudtheta(NTrk), dTaudphi(NTrk);
2184 for(
unsigned int it=0; it<NTrk; it++) {
2186 double trkCharge = 1.;
2187 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
2191 double tmp = 1./(
qOverP*
qOverP) + masses[it]*masses[it];
2192 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
2207 double LXY = Px*dx+Py*dy;
2209 for(
unsigned int it=0; it<NTrk; it++) {
2210 dMdqOverP[it] = -(Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it]-E*dedqOverP[it])/M;
2211 dMdtheta[it] = -(Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/M;
2212 dMdphi[it] = -(Px*dpxdphi[it]+Py*dpydphi[it])/M;
2213 double dPTdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it])/PT;
2214 double dPTdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it])/PT;
2215 double dPTdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/PT;
2216 double dLXYdqOverP = dx*dpxdqOverP[it]+dy*dpydqOverP[it];
2217 double dLXYdtheta = dx*dpxdtheta[it]+dy*dpydtheta[it];
2218 double dLXYdphi = dx*dpxdphi[it]+dy*dpydphi[it];
2219 dTaudqOverP[it] = (LXY*dMdqOverP[it]+M*dLXYdqOverP)/(PT*PT)-(2.*LXY*M*dPTdqOverP)/(PT*PT*PT);
2220 dTaudtheta[it] = (LXY*dMdtheta[it]+M*dLXYdtheta)/(PT*PT)-(2.*LXY*M*dPTdtheta)/(PT*PT*PT);
2221 dTaudphi[it] = (LXY*dMdphi[it]+M*dLXYdphi)/(PT*PT)-(2.*LXY*M*dPTdphi)/(PT*PT*PT);
2223 double dTaudx = (M*Px)/(PT*PT);
2224 double dTaudy = (M*Py)/(PT*PT);
2225 double dTaudx0 = -dTaudx;
2226 double dTaudy0 = -dTaudy;
2228 unsigned int ndim = 0;
2229 if (fullCov.size() != 0) {
2230 ndim = fullCov.rows();
2236 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
2238 for(
unsigned int it=0; it<NTrk; it++) {
2239 D_mat(5*it+0,0) = 0.;
2240 D_mat(5*it+1,0) = 0.;
2241 D_mat(5*it+2,0) = CONST*dTaudphi[it];
2242 D_mat(5*it+3,0) = CONST*dTaudtheta[it];
2243 D_mat(5*it+4,0) = CONST*dTaudqOverP[it];
2244 D_mat(5*it+0,1) = 0.;
2245 D_mat(5*it+1,1) = 0.;
2246 D_mat(5*it+2,1) = dMdphi[it];
2247 D_mat(5*it+3,1) = dMdtheta[it];
2248 D_mat(5*it+4,1) = dMdqOverP[it];
2250 D_mat(5*NTrk+0,0) = CONST*dTaudx;
2251 D_mat(5*NTrk+1,0) = CONST*dTaudy;
2252 D_mat(5*NTrk+2,0) = 0.;
2253 D_mat(5*NTrk+3,0) = CONST*dTaudx0;
2254 D_mat(5*NTrk+4,0) = CONST*dTaudy0;
2255 D_mat(5*NTrk+5,0) = 0.;
2256 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
2257 if (fullCov.size() != 0) {
2258 W_mat.block(0,0,ndim,ndim) = fullCov;
2261 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
2262 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
2264 W_mat.block<3,3>(5*NTrk+3,5*NTrk+3) =
vertex->covariancePosition();
2265 V0_err = D_mat.transpose() * W_mat * D_mat;
2266 }
else if (ndim == 3*NTrk+3) {
2268 D_mat(0,0) = CONST*dTaudx;
2269 D_mat(1,0) = CONST*dTaudy;
2271 for(
unsigned int it=0; it<NTrk; it++) {
2272 D_mat(3*it+3,0) = CONST*dTaudphi[it];
2273 D_mat(3*it+4,0) = CONST*dTaudtheta[it];
2274 D_mat(3*it+5,0) = CONST*dTaudqOverP[it];
2275 D_mat(3*it+3,1) = dMdphi[it];
2276 D_mat(3*it+4,1) = dMdtheta[it];
2277 D_mat(3*it+5,1) = dMdqOverP[it];
2279 D_mat(3*NTrk+3,0) = CONST*dTaudx0;
2280 D_mat(3*NTrk+4,0) = CONST*dTaudy0;
2281 D_mat(3*NTrk+5,0) = 0.;
2282 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
2283 W_mat.block(0,0,ndim,ndim) = fullCov;
2284 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
2285 V0_err = D_mat.transpose() * W_mat * D_mat;
2296 for(
unsigned int it=0; it<NTrk; it++){
2299 V0_cov(5*it+2,5*it+2) = (*cov_tmp)(2,2);
2300 V0_cov(5*it+2,5*it+3) = (*cov_tmp)(2,3);
2301 V0_cov(5*it+2,5*it+4) = (*cov_tmp)(2,4);
2302 V0_cov(5*it+3,5*it+3) = (*cov_tmp)(3,3);
2303 V0_cov(5*it+3,5*it+4) = (*cov_tmp)(3,4);
2304 V0_cov(5*it+4,5*it+4) = (*cov_tmp)(4,4);
2305 V0_cov(5*it+3,5*it+2) = (*cov_tmp)(2,3);
2306 V0_cov(5*it+4,5*it+2) = (*cov_tmp)(2,4);
2307 V0_cov(5*it+4,5*it+3) = (*cov_tmp)(3,4);
2317 if (masses.size() != NTrk) {
2318 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
2322 double CONST = 1000./299.792;
2325 double dx = vert.x();
2326 double dy = vert.y();
2328 double E=0., Px=0., Py=0., Pz=0.;
2329 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
2330 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
2331 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk), dedqOverP(NTrk);
2332 std::vector<double>dMdqOverP(NTrk), dMdtheta(NTrk), dMdphi(NTrk);
2333 std::vector<double>dTaudqOverP(NTrk), dTaudtheta(NTrk), dTaudphi(NTrk);
2336 for(
unsigned int it=0; it<NTrk; it++) {
2338 double trkCharge = 1.;
2339 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
2343 double tmp = 1./(
qOverP*
qOverP) + masses[it]*masses[it];
2344 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
2359 double LXY = Px*dx+Py*dy;
2361 for(
unsigned int it=0; it<NTrk; it++) {
2362 dMdqOverP[it] = -(Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it]-E*dedqOverP[it])/M;
2363 dMdtheta[it] = -(Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/M;
2364 dMdphi[it] = -(Px*dpxdphi[it]+Py*dpydphi[it])/M;
2365 double dPTdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it])/PT;
2366 double dPTdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it])/PT;
2367 double dPTdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/PT;
2368 double dLXYdqOverP = dx*dpxdqOverP[it]+dy*dpydqOverP[it];
2369 double dLXYdtheta = dx*dpxdtheta[it]+dy*dpydtheta[it];
2370 double dLXYdphi = dx*dpxdphi[it]+dy*dpydphi[it];
2371 dTaudqOverP[it] = (LXY*dMdqOverP[it]+M*dLXYdqOverP)/(PT*PT)-(2.*LXY*M*dPTdqOverP)/(PT*PT*PT);
2372 dTaudtheta[it] = (LXY*dMdtheta[it]+M*dLXYdtheta)/(PT*PT)-(2.*LXY*M*dPTdtheta)/(PT*PT*PT);
2373 dTaudphi[it] = (LXY*dMdphi[it]+M*dLXYdphi)/(PT*PT)-(2.*LXY*M*dPTdphi)/(PT*PT*PT);
2375 double dTaudx = (M*Px)/(PT*PT);
2376 double dTaudy = (M*Py)/(PT*PT);
2377 double dTaudx0 = -dTaudx;
2378 double dTaudy0 = -dTaudy;
2380 unsigned int ndim = 0;
2381 if (fullCov.size() != 0) {
2382 ndim = fullCov.rows();
2387 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
2389 for(
unsigned int it=0; it<NTrk; it++) {
2390 D_mat(5*it+0,0) = 0.;
2391 D_mat(5*it+1,0) = 0.;
2392 D_mat(5*it+2,0) = CONST*dTaudphi[it];
2393 D_mat(5*it+3,0) = CONST*dTaudtheta[it];
2394 D_mat(5*it+4,0) = CONST*dTaudqOverP[it];
2395 D_mat(5*it+0,1) = 0.;
2396 D_mat(5*it+1,1) = 0.;
2397 D_mat(5*it+2,1) = dMdphi[it];
2398 D_mat(5*it+3,1) = dMdtheta[it];
2399 D_mat(5*it+4,1) = dMdqOverP[it];
2401 D_mat(5*NTrk+0,0) = CONST*dTaudx;
2402 D_mat(5*NTrk+1,0) = CONST*dTaudy;
2403 D_mat(5*NTrk+2,0) = 0.;
2404 D_mat(5*NTrk+3,0) = CONST*dTaudx0;
2405 D_mat(5*NTrk+4,0) = CONST*dTaudy0;
2406 D_mat(5*NTrk+5,0) = 0.;
2407 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
2408 if (fullCov.size() != 0) {
2409 W_mat.block(0,0,ndim,ndim) = fullCov;
2412 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
2413 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
2415 W_mat.block<3,3>(5*NTrk+3,5*NTrk) =
vertex->covariancePosition();
2416 V0_err = D_mat.transpose() * W_mat * D_mat;
2417 }
else if (ndim == 3*NTrk+3) {
2419 D_mat(0,0) = CONST*dTaudx;
2420 D_mat(1,0) = CONST*dTaudy;
2422 for(
unsigned int it=0; it<NTrk; it++) {
2423 D_mat(3*it+3,0) = CONST*dTaudphi[it];
2424 D_mat(3*it+4,0) = CONST*dTaudtheta[it];
2425 D_mat(3*it+5,0) = CONST*dTaudqOverP[it];
2426 D_mat(3*it+3,1) = dMdphi[it];
2427 D_mat(3*it+4,1) = dMdtheta[it];
2428 D_mat(3*it+5,1) = dMdqOverP[it];
2430 D_mat(3*NTrk+3,0) = CONST*dTaudx0;
2431 D_mat(3*NTrk+4,0) = CONST*dTaudy0;
2432 D_mat(3*NTrk+5,0) = 0.;
2433 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
2434 W_mat.block(0,0,ndim,ndim) = fullCov;
2435 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
2436 V0_err = D_mat.transpose() * W_mat * D_mat;
2447 const std::vector<float> &matrix = vxCandidate->
covariance();
2451 if ( matrix.size() == (3*NTrk+3)*(3*NTrk+3+1)/2) {
2453 }
else if (matrix.size() == (5*NTrk+3)*(5*NTrk+3+1)/2) {
2462 for (
int i=1; i<= ndim; i++) {
2463 for (
int j=1; j<=i; j++){
2465 mtx(i-1,j-1)=matrix[ij];
2467 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.