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 ATH_MSG_ERROR(
"a0zError: Divisor is zero - returning zero.");
730 double da0dx = (Px*Pz)/P2;
731 double da0dy = (Py*Pz)/P2;
732 double da0dz = (Pz*Pz)/P2 - 1.;
733 double da0dx0 = -da0dx;
734 double da0dy0 = -da0dy;
735 double da0dz0 = -da0dz;
736 for(
unsigned int it=0; it<NTrk; it++) {
737 double dP2dqOverP = 2.*(Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it]);
738 double dP2dtheta = 2.*(Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it]);
739 double dP2dphi = 2.*(Px*dpxdphi[it]+Py*dpydphi[it]);
740 da0dqOverP[it] = (B*(P2*dpzdqOverP[it]-Pz*dP2dqOverP) +
741 Pz*P2*(dx*dpxdqOverP[it]+dy*dpydqOverP[it]+dz*dpzdqOverP[it]))/(P2*P2);
742 da0dtheta[it] = (B*(P2*dpzdtheta[it]-Pz*dP2dtheta) +
743 Pz*P2*(dx*dpxdtheta[it]+dy*dpydtheta[it]+dz*dpzdtheta[it]))/(P2*P2);
744 da0dphi[it] = -(B*Pz*dP2dphi -
745 Pz*P2*(dx*dpxdphi[it]+dy*dpydphi[it]))/(P2*P2);
748 unsigned int ndim = 0;
749 if (fullCov.size() != 0) {
750 ndim = fullCov.rows();
756 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
758 for(
unsigned int it=0; it<NTrk; it++) {
761 D_vec(5*it+2) = da0dphi[it];
762 D_vec(5*it+3) = da0dtheta[it];
763 D_vec(5*it+4) = da0dqOverP[it];
765 D_vec(5*NTrk+0) = da0dx;
766 D_vec(5*NTrk+1) = da0dy;
767 D_vec(5*NTrk+2) = da0dz;
768 D_vec(5*NTrk+3) = da0dx0;
769 D_vec(5*NTrk+4) = da0dy0;
770 D_vec(5*NTrk+5) = da0dz0;
773 if (fullCov.size() != 0) {
774 W_mat.block(0,0,ndim,ndim) = fullCov;
777 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
778 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
780 W_mat.block<3,3>(5*NTrk+3,5*NTrk+3) =
vertex->covariancePosition();
781 V0_err = D_vec.transpose() * W_mat * D_vec;
782 }
else if (ndim == 3*NTrk+3) {
787 for(
unsigned int it=0; it<NTrk; it++) {
788 D_vec(3*it+3) = da0dphi[it];
789 D_vec(3*it+4) = da0dtheta[it];
790 D_vec(3*it+5) = da0dqOverP[it];
792 D_vec(3*NTrk+3) = da0dx0;
793 D_vec(3*NTrk+4) = da0dy0;
794 D_vec(3*NTrk+5) = da0dz0;
797 W_mat.block(0,0,ndim,ndim) = fullCov;
798 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
799 V0_err = D_vec.transpose() * W_mat * D_vec;
805 double a0Errsq = V0_err(0,0);
806 if (a0Errsq <= 0.)
ATH_MSG_DEBUG(
"a0Error: negative sqrt a0Errsq " << a0Errsq);
807 double a0Err = (a0Errsq>0.) ? sqrt(a0Errsq) : 0.;
820 double dx = vert.x();
821 double dy = vert.y();
822 double dz = vert.z();
823 double Px=0., Py=0., Pz=0.;
824 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
825 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
826 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk);
827 std::vector<double>da0dqOverP(NTrk), da0dtheta(NTrk), da0dphi(NTrk);
830 for(
unsigned int it=0; it<NTrk; it++) {
832 double trkCharge = 1.;
833 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
862 double P = sqrt(Px*Px+Py*Py+Pz*Pz);
863 double r = sqrt(dx*dx+dy*dy+dz*dz);
865 double da0dx = (Px/
P*
r*cosineTheta - dx)/a0val;
866 double da0dy = (Py/
P*
r*cosineTheta - dy)/a0val;
867 double da0dz = (Pz/
P*
r*cosineTheta - dz)/a0val;
868 double da0dx0 = -da0dx;
869 double da0dy0 = -da0dy;
870 double da0dz0 = -da0dz;
871 for(
unsigned int it=0; it<NTrk; it++) {
872 da0dqOverP[it] = -(
r*cosineTheta/
P)*(da0dx*dpxdqOverP[it]+da0dy*dpydqOverP[it]+da0dz*dpzdqOverP[it]);
873 da0dtheta[it] = -(
r*cosineTheta/
P)*(da0dx*dpxdtheta[it]+da0dy*dpydtheta[it]+da0dz*dpzdtheta[it]);
874 da0dphi[it] = -(
r*cosineTheta/
P)*(da0dx*dpxdphi[it]+da0dy*dpydphi[it]);
877 unsigned int ndim = 0;
878 if (fullCov.size() != 0) {
879 ndim = fullCov.rows();
885 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
887 for(
unsigned int it=0; it<NTrk; it++) {
890 D_vec(5*it+2) = da0dphi[it];
891 D_vec(5*it+3) = da0dtheta[it];
892 D_vec(5*it+4) = da0dqOverP[it];
894 D_vec(5*NTrk+0) = da0dx;
895 D_vec(5*NTrk+1) = da0dy;
896 D_vec(5*NTrk+2) = da0dz;
897 D_vec(5*NTrk+3) = da0dx0;
898 D_vec(5*NTrk+4) = da0dy0;
899 D_vec(5*NTrk+5) = da0dz0;
902 if (fullCov.size() != 0) {
903 W_mat.block(0,0,ndim,ndim) = fullCov;
906 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
907 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
909 W_mat.block<3,3>(5*NTrk+3,5*NTrk+3) =
vertex->covariancePosition();
910 V0_err = D_vec.transpose() * W_mat * D_vec;
911 }
else if (ndim == 3*NTrk+3) {
916 for(
unsigned int it=0; it<NTrk; it++) {
917 D_vec(3*it+3) = da0dphi[it];
918 D_vec(3*it+4) = da0dtheta[it];
919 D_vec(3*it+5) = da0dqOverP[it];
921 D_vec(3*NTrk+3) = da0dx0;
922 D_vec(3*NTrk+4) = da0dy0;
923 D_vec(3*NTrk+5) = da0dz0;
926 W_mat.block(0,0,ndim,ndim) = fullCov;
927 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
928 V0_err = D_vec.transpose() * W_mat * D_vec;
934 double a0Errsq = V0_err(0,0);
935 if (a0Errsq <= 0.)
ATH_MSG_DEBUG(
"a0Error: negative sqrt a0Errsq " << a0Errsq);
936 double a0Err = (a0Errsq>0.) ? sqrt(a0Errsq) : 0.;
943 double dx = vert.x();
944 double dy = vert.y();
946 double dxy = (mom.x()*dx + mom.y()*dy)/mom.perp();
953 double dx = vert.x();
954 double dy = vert.y();
957 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
958 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
959 std::vector<double>dLxydqOverP(NTrk), dLxydtheta(NTrk), dLxydphi(NTrk);
962 for(
unsigned int it=0; it<NTrk; it++) {
964 double trkCharge = 1.;
965 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
978 double PTsq = Px*Px+Py*Py;
979 double PT = (PTsq>0.) ? sqrt(PTsq) : 0.;
981 ATH_MSG_ERROR(
"lxyError: Divisor is zero - returning zero.");
984 double LXYoverPT = (Px*dx+Py*dy)/PTsq;
986 for(
unsigned int it=0; it<NTrk; it++) {
987 double dPTdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it])/PT;
988 double dPTdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it])/PT;
989 double dPTdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/PT;
990 dLxydqOverP[it] = (dx*dpxdqOverP[it]+dy*dpydqOverP[it])/PT-LXYoverPT*dPTdqOverP;
991 dLxydtheta[it] = (dx*dpxdtheta[it]+dy*dpydtheta[it])/PT-LXYoverPT*dPTdtheta;
992 dLxydphi[it] = (dx*dpxdphi[it]+dy*dpydphi[it])/PT-LXYoverPT*dPTdphi;
994 double dLxydx = Px/PT;
995 double dLxydy = Py/PT;
996 double dLxydx0 = -dLxydx;
997 double dLxydy0 = -dLxydy;
999 unsigned int ndim = 0;
1000 if (fullCov.size() != 0) {
1001 ndim = fullCov.rows();
1007 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
1009 for(
unsigned int it=0; it<NTrk; it++) {
1012 D_vec(5*it+2) = dLxydphi[it];
1013 D_vec(5*it+3) = dLxydtheta[it];
1014 D_vec(5*it+4) = dLxydqOverP[it];
1016 D_vec(5*NTrk+0) = dLxydx;
1017 D_vec(5*NTrk+1) = dLxydy;
1018 D_vec(5*NTrk+2) = 0.;
1019 D_vec(5*NTrk+3) = dLxydx0;
1020 D_vec(5*NTrk+4) = dLxydy0;
1021 D_vec(5*NTrk+5) = 0.;
1023 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
1024 if (fullCov.size() != 0) {
1025 W_mat.block(0,0,ndim,ndim) = fullCov;
1028 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
1029 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
1031 W_mat.block<3,3>(5*NTrk+3,5*NTrk+3) =
vertex->covariancePosition();
1032 V0_err = D_vec.transpose() * W_mat * D_vec;
1033 }
else if (ndim == 3*NTrk+3) {
1038 for(
unsigned int it=0; it<NTrk; it++) {
1039 D_vec(3*it+3) = dLxydphi[it];
1040 D_vec(3*it+4) = dLxydtheta[it];
1041 D_vec(3*it+5) = dLxydqOverP[it];
1043 D_vec(3*NTrk+3) = dLxydx0;
1044 D_vec(3*NTrk+4) = dLxydy0;
1045 D_vec(3*NTrk+5) = 0.;
1047 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
1048 W_mat.block(0,0,ndim,ndim) = fullCov;
1049 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
1050 V0_err = D_vec.transpose() * W_mat * D_vec;
1056 double LxyErrsq = V0_err(0,0);
1057 if (LxyErrsq <= 0.)
ATH_MSG_DEBUG(
"lxyError: negative sqrt LxyErrsq " << LxyErrsq);
1058 return (LxyErrsq>0.) ? sqrt(LxyErrsq) : 0.;
1064 double dx = vert.x();
1065 double dy = vert.y();
1066 double dz = vert.z();
1068 double dxyz= (mom.x()*dx + mom.y()*dy + mom.z()*dz)/mom.mag();
1075 double dx = vert.x();
1076 double dy = vert.y();
1077 double dz = vert.z();
1079 double Px=0., Py=0., Pz=0.;
1080 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
1081 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
1082 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk);
1083 std::vector<double>dLxyzdqOverP(NTrk), dLxyzdtheta(NTrk), dLxyzdphi(NTrk);
1086 for(
unsigned int it=0; it<NTrk; it++) {
1088 double trkCharge = 1.;
1089 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
1105 double Psq = Px*Px+Py*Py+Pz*Pz;
1106 double P = (Psq>0.) ? sqrt(Psq) : 0.;
1108 ATH_MSG_ERROR(
"lxyzError: Divisor is zero - returning zero.");
1111 double LXYZoverP = (Px*dx+Py*dy+Pz*dz)/Psq;
1113 for(
unsigned int it=0; it<NTrk; it++) {
1114 double dPdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it])/
P;
1115 double dPdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/
P;
1116 double dPdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/
P;
1117 dLxyzdqOverP[it] = (dx*dpxdqOverP[it]+dy*dpydqOverP[it]+dz*dpzdqOverP[it])/
P-LXYZoverP*dPdqOverP;
1118 dLxyzdtheta[it] = (dx*dpxdtheta[it]+dy*dpydtheta[it]+dz*dpzdtheta[it])/
P-LXYZoverP*dPdtheta;
1119 dLxyzdphi[it] = (dx*dpxdphi[it]+dy*dpydphi[it])/
P-LXYZoverP*dPdphi;
1121 double dLxyzdx = Px/
P;
1122 double dLxyzdy = Py/
P;
1123 double dLxyzdz = Pz/
P;
1124 double dLxyzdx0 = -dLxyzdx;
1125 double dLxyzdy0 = -dLxyzdy;
1126 double dLxyzdz0 = -dLxyzdz;
1128 unsigned int ndim = 0;
1129 if (fullCov.size() != 0) {
1130 ndim = fullCov.rows();
1136 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
1138 for(
unsigned int it=0; it<NTrk; it++) {
1141 D_vec(5*it+2) = dLxyzdphi[it];
1142 D_vec(5*it+3) = dLxyzdtheta[it];
1143 D_vec(5*it+4) = dLxyzdqOverP[it];
1145 D_vec(5*NTrk+0) = dLxyzdx;
1146 D_vec(5*NTrk+1) = dLxyzdy;
1147 D_vec(5*NTrk+2) = dLxyzdz;
1148 D_vec(5*NTrk+3) = dLxyzdx0;
1149 D_vec(5*NTrk+4) = dLxyzdy0;
1150 D_vec(5*NTrk+5) = dLxyzdz0;
1152 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
1153 if (fullCov.size() != 0) {
1154 W_mat.block(0,0,ndim,ndim) = fullCov;
1157 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
1158 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
1160 W_mat.block<3,3>(5*NTrk+3,5*NTrk+3) =
vertex->covariancePosition();
1161 V0_err = D_vec.transpose() * W_mat * D_vec;
1162 }
else if (ndim == 3*NTrk+3) {
1167 for(
unsigned int it=0; it<NTrk; it++) {
1168 D_vec(3*it+3) = dLxyzdphi[it];
1169 D_vec(3*it+4) = dLxyzdtheta[it];
1170 D_vec(3*it+5) = dLxyzdqOverP[it];
1172 D_vec(3*NTrk+3) = dLxyzdx0;
1173 D_vec(3*NTrk+4) = dLxyzdy0;
1174 D_vec(3*NTrk+5) = dLxyzdz0;
1176 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
1177 W_mat.block(0,0,ndim,ndim) = fullCov;
1178 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
1179 V0_err = D_vec.transpose() * W_mat * D_vec;
1185 double LxyzErrsq = V0_err(0,0);
1186 if (LxyzErrsq <= 0.)
ATH_MSG_DEBUG(
"lxyzError: negative sqrt LxyzErrsq " << LxyzErrsq);
1187 return (LxyzErrsq>0.) ? sqrt(LxyzErrsq) : 0.;
1192 std::array<double, 2> masses = {posTrackMass, negTrackMass};
1200 if (masses.size() != NTrk) {
1201 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
1205 double CONST = 1000./299.792;
1209 return CONST*M*LXY/PT;
1214 std::array<double, 2> masses = {posTrackMass, negTrackMass};
1216 return tau(vxCandidate,
vertex,masses,massV0);
1222 if (masses.size() != NTrk) {
1223 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
1229 double descr = cov(0,0)*cov(1,1)-cov(0,1)*cov(0,1);
1230 double cov_i11 = cov(1,1)/descr;
1231 double cov_i12 = -cov(0,1)/descr;
1232 double deltaTau = -(massV0-mass)*cov_i12/cov_i11;
1233 return Tau + deltaTau;
1239 double CONST = 1000./299.792;
1242 return CONST*M*LXY/PT;
1248 std::array<double, 2> masses = {posTrackMass, negTrackMass};
1257 if (masses.size() != NTrk) {
1258 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
1262 double CONST = 1000./299.792;
1265 double dx = vert.x();
1266 double dy = vert.y();
1268 double E=0., Px=0., Py=0., Pz=0.;
1269 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
1270 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
1271 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk), dedqOverP(NTrk);
1272 std::vector<double>dTaudqOverP(NTrk), dTaudtheta(NTrk), dTaudphi(NTrk);
1275 for(
unsigned int it=0; it<NTrk; it++) {
1277 double trkCharge = 1.;
1278 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
1282 double tmp = 1./(
qOverP*
qOverP) + masses[it]*masses[it];
1283 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
1298 double LXY = Px*dx+Py*dy;
1300 for(
unsigned int it=0; it<NTrk; it++) {
1301 double dMdqOverP = -(Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it]-E*dedqOverP[it])/M;
1302 double dMdtheta = -(Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/M;
1303 double dMdphi = -(Px*dpxdphi[it]+Py*dpydphi[it])/M;
1304 double dPTdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it])/PT;
1305 double dPTdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it])/PT;
1306 double dPTdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/PT;
1307 double dLXYdqOverP = dx*dpxdqOverP[it]+dy*dpydqOverP[it];
1308 double dLXYdtheta = dx*dpxdtheta[it]+dy*dpydtheta[it];
1309 double dLXYdphi = dx*dpxdphi[it]+dy*dpydphi[it];
1310 dTaudqOverP[it] = (LXY*dMdqOverP+M*dLXYdqOverP)/(PT*PT)-(2.*LXY*M*dPTdqOverP)/(PT*PT*PT);
1311 dTaudtheta[it] = (LXY*dMdtheta+M*dLXYdtheta)/(PT*PT)-(2.*LXY*M*dPTdtheta)/(PT*PT*PT);
1312 dTaudphi[it] = (LXY*dMdphi+M*dLXYdphi)/(PT*PT)-(2.*LXY*M*dPTdphi)/(PT*PT*PT);
1314 double dTaudx = (M*Px)/(PT*PT);
1315 double dTaudy = (M*Py)/(PT*PT);
1316 double dTaudx0 = -dTaudx;
1317 double dTaudy0 = -dTaudy;
1319 unsigned int ndim = 0;
1320 if (fullCov.size() != 0) {
1321 ndim = fullCov.rows();
1327 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
1329 for(
unsigned int it=0; it<NTrk; it++) {
1332 D_vec(5*it+2) = dTaudphi[it];
1333 D_vec(5*it+3) = dTaudtheta[it];
1334 D_vec(5*it+4) = dTaudqOverP[it];
1336 D_vec(5*NTrk+0) = dTaudx;
1337 D_vec(5*NTrk+1) = dTaudy;
1338 D_vec(5*NTrk+2) = 0.;
1339 D_vec(5*NTrk+3) = dTaudx0;
1340 D_vec(5*NTrk+4) = dTaudy0;
1341 D_vec(5*NTrk+5) = 0.;
1343 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
1344 if (fullCov.size() != 0) {
1345 W_mat.block(0,0,ndim,ndim) = fullCov;
1348 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
1349 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
1351 W_mat.block<3,3>(5*NTrk+3,5*NTrk+3) =
vertex->covariancePosition();
1352 V0_err = D_vec.transpose() * W_mat * D_vec;
1353 }
else if (ndim == 3*NTrk+3) {
1358 for(
unsigned int it=0; it<NTrk; it++) {
1359 D_vec(3*it+3) = dTaudphi[it];
1360 D_vec(3*it+4) = dTaudtheta[it];
1361 D_vec(3*it+5) = dTaudqOverP[it];
1363 D_vec(3*NTrk+3) = dTaudx0;
1364 D_vec(3*NTrk+4) = dTaudy0;
1365 D_vec(3*NTrk+5) = 0.;
1367 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
1368 W_mat.block(0,0,ndim,ndim) = fullCov;
1369 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
1370 V0_err = D_vec.transpose() * W_mat * D_vec;
1376 double tauErrsq = V0_err(0,0);
1377 if (tauErrsq <= 0.)
ATH_MSG_DEBUG(
"tauError: negative sqrt tauErrsq " << tauErrsq);
1378 double tauErr = (tauErrsq>0.) ? sqrt(tauErrsq) : 0.;
1379 return CONST*tauErr;
1384 std::array<double, 2> masses = {posTrackMass, negTrackMass};
1392 if (masses.size() != NTrk) {
1393 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
1396 double error = -999999.;
1398 double descr = cov(0,0)*cov(1,1)-cov(0,1)*cov(0,1);
1399 double cov_i11 = cov(1,1)/descr;
1400 if (cov_i11 > 0.)
error = 1./sqrt(cov_i11);
1408 double CONST = 1000./299.792;
1411 double dx = vecsub.x();
1412 double dy = vecsub.y();
1414 double Px=0., Py=0.;
1415 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
1416 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
1417 std::vector<double>dPTdtheta(NTrk), dPTdphi(NTrk);
1418 std::vector<double>dTaudqOverP(NTrk), dTaudtheta(NTrk), dTaudphi(NTrk);
1421 for(
unsigned int it=0; it<NTrk; it++) {
1423 double trkCharge = 1.;
1424 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
1437 double LXY = Px*dx+Py*dy;
1439 for(
unsigned int it=0; it<NTrk; it++) {
1440 double dPTdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it])/PT;
1441 double dPTdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it])/PT;
1442 double dPTdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/PT;
1443 double dLXYdqOverP = dx*dpxdqOverP[it]+dy*dpydqOverP[it];
1444 double dLXYdtheta = dx*dpxdtheta[it]+dy*dpydtheta[it];
1445 double dLXYdphi = dx*dpxdphi[it]+dy*dpydphi[it];
1446 dTaudqOverP[it] = M*dLXYdqOverP/(PT*PT)-(2.*LXY*M*dPTdqOverP)/(PT*PT*PT);
1447 dTaudtheta[it] = M*dLXYdtheta/(PT*PT)-(2.*LXY*M*dPTdtheta)/(PT*PT*PT);
1448 dTaudphi[it] = M*dLXYdphi/(PT*PT)-(2.*LXY*M*dPTdphi)/(PT*PT*PT);
1450 double dTaudx = (M*Px)/(PT*PT);
1451 double dTaudy = (M*Py)/(PT*PT);
1452 double dTaudx0 = -dTaudx;
1453 double dTaudy0 = -dTaudy;
1455 unsigned int ndim = 0;
1456 if (fullCov.size() != 0) {
1457 ndim = fullCov.rows();
1463 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
1465 for(
unsigned int it=0; it<NTrk; it++) {
1468 D_vec(5*it+2) = dTaudphi[it];
1469 D_vec(5*it+3) = dTaudtheta[it];
1470 D_vec(5*it+4) = dTaudqOverP[it];
1472 D_vec(5*NTrk+0) = dTaudx;
1473 D_vec(5*NTrk+1) = dTaudy;
1474 D_vec(5*NTrk+2) = 0.;
1475 D_vec(5*NTrk+3) = dTaudx0;
1476 D_vec(5*NTrk+4) = dTaudy0;
1477 D_vec(5*NTrk+5) = 0.;
1479 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
1480 if (fullCov.size() != 0) {
1481 W_mat.block(0,0,ndim,ndim) = fullCov;
1484 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
1485 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
1487 W_mat.block<3,3>(5*NTrk+3,5*NTrk+3) =
vertex->covariancePosition();
1488 V0_err = D_vec.transpose() * W_mat * D_vec;
1489 }
else if (ndim == 3*NTrk+3) {
1494 for(
unsigned int it=0; it<NTrk; it++) {
1495 D_vec(3*it+3) = dTaudphi[it];
1496 D_vec(3*it+4) = dTaudtheta[it];
1497 D_vec(3*it+5) = dTaudqOverP[it];
1499 D_vec(3*NTrk+3) = dTaudx0;
1500 D_vec(3*NTrk+4) = dTaudy0;
1501 D_vec(3*NTrk+5) = 0.;
1503 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
1504 W_mat.block(0,0,ndim,ndim) = fullCov;
1505 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
1506 V0_err = D_vec.transpose() * W_mat * D_vec;
1512 double tauErrsq = V0_err(0,0);
1513 if (tauErrsq <= 0.)
ATH_MSG_DEBUG(
"tauError: negative sqrt tauErrsq " << tauErrsq);
1514 double tauErr = (tauErrsq>0.) ? sqrt(tauErrsq) : 0.;
1515 return CONST*tauErr;
1521 if (masses.size() != NTrk) {
1522 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
1526 double CONST = 1000./299.792;
1530 return CONST*M*LXYZ/
P;
1536 double CONST = 1000./299.792;
1539 return CONST*M*LXYZ/
P;
1546 if (masses.size() != NTrk) {
1547 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
1551 double CONST = 1000./299.792;
1554 double dx = vert.x();
1555 double dy = vert.y();
1556 double dz = vert.z();
1558 double E=0., Px=0., Py=0., Pz=0.;
1559 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
1560 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
1561 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk), dedqOverP(NTrk);
1562 std::vector<double>dTaudqOverP(NTrk), dTaudtheta(NTrk), dTaudphi(NTrk);
1565 for(
unsigned int it=0; it<NTrk; it++) {
1567 double trkCharge = 1.;
1568 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
1572 double tmp = 1./(
qOverP*
qOverP) + masses[it]*masses[it];
1573 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
1588 double LXYZ = Px*dx+Py*dy+Pz*dz;
1590 for(
unsigned int it=0; it<NTrk; it++) {
1591 double dMdqOverP = -(Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it]-E*dedqOverP[it])/M;
1592 double dMdtheta = -(Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/M;
1593 double dMdphi = -(Px*dpxdphi[it]+Py*dpydphi[it])/M;
1594 double dPdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it])/
P;
1595 double dPdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/
P;
1596 double dPdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/
P;
1597 double dLXYZdqOverP = dx*dpxdqOverP[it]+dy*dpydqOverP[it]+dz*dpzdqOverP[it];
1598 double dLXYZdtheta = dx*dpxdtheta[it]+dy*dpydtheta[it]+dz*dpzdtheta[it];
1599 double dLXYZdphi = dx*dpxdphi[it]+dy*dpydphi[it];
1600 dTaudqOverP[it] = (LXYZ*dMdqOverP+M*dLXYZdqOverP)/(
P*
P)-(2.*LXYZ*M*dPdqOverP)/(
P*
P*
P);
1601 dTaudtheta[it] = (LXYZ*dMdtheta+M*dLXYZdtheta)/(
P*
P)-(2.*LXYZ*M*dPdtheta)/(
P*
P*
P);
1602 dTaudphi[it] = (LXYZ*dMdphi+M*dLXYZdphi)/(
P*
P)-(2.*LXYZ*M*dPdphi)/(
P*
P*
P);
1604 double dTaudx = (M*Px)/(
P*
P);
1605 double dTaudy = (M*Py)/(
P*
P);
1606 double dTaudz = (M*Pz)/(
P*
P);
1607 double dTaudx0 = -dTaudx;
1608 double dTaudy0 = -dTaudy;
1609 double dTaudz0 = -dTaudz;
1611 unsigned int ndim = 0;
1612 if (fullCov.size() != 0) {
1613 ndim = fullCov.rows();
1619 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
1621 for(
unsigned int it=0; it<NTrk; it++) {
1624 D_vec(5*it+2) = dTaudphi[it];
1625 D_vec(5*it+3) = dTaudtheta[it];
1626 D_vec(5*it+4) = dTaudqOverP[it];
1628 D_vec(5*NTrk+0) = dTaudx;
1629 D_vec(5*NTrk+1) = dTaudy;
1630 D_vec(5*NTrk+2) = dTaudz;
1631 D_vec(5*NTrk+3) = dTaudx0;
1632 D_vec(5*NTrk+4) = dTaudy0;
1633 D_vec(5*NTrk+5) = dTaudz0;
1635 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
1636 if (fullCov.size() != 0) {
1637 W_mat.block(0,0,ndim,ndim) = fullCov;
1640 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
1641 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
1643 W_mat.block<3,3>(5*NTrk+3,5*NTrk+3) =
vertex->covariancePosition();
1644 V0_err = D_vec.transpose() * W_mat * D_vec;
1645 }
else if (ndim == 3*NTrk+3) {
1650 for(
unsigned int it=0; it<NTrk; it++) {
1651 D_vec(3*it+3) = dTaudphi[it];
1652 D_vec(3*it+4) = dTaudtheta[it];
1653 D_vec(3*it+5) = dTaudqOverP[it];
1655 D_vec(3*NTrk+3) = dTaudx0;
1656 D_vec(3*NTrk+4) = dTaudy0;
1657 D_vec(3*NTrk+5) = dTaudz0;
1659 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
1660 W_mat.block(0,0,ndim,ndim) = fullCov;
1661 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
1662 V0_err = D_vec.transpose() * W_mat * D_vec;
1668 double tauErrsq = V0_err(0,0);
1669 if (tauErrsq <= 0.)
ATH_MSG_DEBUG(
"tauError: negative sqrt tauErrsq " << tauErrsq);
1670 double tauErr = (tauErrsq>0.) ? sqrt(tauErrsq) : 0.;
1671 return CONST*tauErr;
1678 double CONST = 1000./299.792;
1681 double dx = vecsub.x();
1682 double dy = vecsub.y();
1683 double dz = vecsub.z();
1685 double Px=0., Py=0., Pz=0.;
1686 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
1687 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
1688 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk);
1689 std::vector<double>dTaudqOverP(NTrk), dTaudtheta(NTrk), dTaudphi(NTrk);
1692 for(
unsigned int it=0; it<NTrk; it++) {
1694 double trkCharge = 1.;
1695 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
1711 double LXYZ = Px*dx+Py*dy+Pz*dz;
1713 for(
unsigned int it=0; it<NTrk; it++) {
1714 double dPdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it])/
P;
1715 double dPdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/
P;
1716 double dPdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/
P;
1717 double dLXYZdqOverP = dx*dpxdqOverP[it]+dy*dpydqOverP[it]+dz*dpzdqOverP[it];
1718 double dLXYZdtheta = dx*dpxdtheta[it]+dy*dpydtheta[it]+dz*dpzdtheta[it];
1719 double dLXYZdphi = dx*dpxdphi[it]+dy*dpydphi[it];
1720 dTaudqOverP[it] = M*dLXYZdqOverP/(
P*
P)-(2.*LXYZ*M*dPdqOverP)/(
P*
P*
P);
1721 dTaudtheta[it] = M*dLXYZdtheta/(
P*
P)-(2.*LXYZ*M*dPdtheta)/(
P*
P*
P);
1722 dTaudphi[it] = M*dLXYZdphi/(
P*
P)-(2.*LXYZ*M*dPdphi)/(
P*
P*
P);
1724 double dTaudx = (M*Px)/(
P*
P);
1725 double dTaudy = (M*Py)/(
P*
P);
1726 double dTaudz = (M*Pz)/(
P*
P);
1727 double dTaudx0 = -dTaudx;
1728 double dTaudy0 = -dTaudy;
1729 double dTaudz0 = -dTaudz;
1731 unsigned int ndim = 0;
1732 if (fullCov.size() != 0) {
1733 ndim = fullCov.rows();
1739 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
1741 for(
unsigned int it=0; it<NTrk; it++) {
1744 D_vec(5*it+2) = dTaudphi[it];
1745 D_vec(5*it+3) = dTaudtheta[it];
1746 D_vec(5*it+4) = dTaudqOverP[it];
1748 D_vec(5*NTrk+0) = dTaudx;
1749 D_vec(5*NTrk+1) = dTaudy;
1750 D_vec(5*NTrk+2) = dTaudz;
1751 D_vec(5*NTrk+3) = dTaudx0;
1752 D_vec(5*NTrk+4) = dTaudy0;
1753 D_vec(5*NTrk+5) = dTaudz0;
1755 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
1756 if (fullCov.size() != 0) {
1757 W_mat.block(0,0,ndim,ndim) = fullCov;
1760 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
1761 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
1763 W_mat.block<3,3>(5*NTrk+3,5*NTrk+3) =
vertex->covariancePosition();
1764 V0_err = D_vec.transpose() * W_mat * D_vec;
1765 }
else if (ndim == 3*NTrk+3) {
1770 for(
unsigned int it=0; it<NTrk; it++) {
1771 D_vec(3*it+3) = dTaudphi[it];
1772 D_vec(3*it+4) = dTaudtheta[it];
1773 D_vec(3*it+5) = dTaudqOverP[it];
1775 D_vec(3*NTrk+3) = dTaudx0;
1776 D_vec(3*NTrk+4) = dTaudy0;
1777 D_vec(3*NTrk+5) = dTaudz0;
1779 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
1780 W_mat.block(0,0,ndim,ndim) = fullCov;
1781 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
1782 V0_err = D_vec.transpose() * W_mat * D_vec;
1788 double tauErrsq = V0_err(0,0);
1789 if (tauErrsq <= 0.)
ATH_MSG_DEBUG(
"tauError: negative sqrt tauErrsq " << tauErrsq);
1790 double tauErr = (tauErrsq>0.) ? sqrt(tauErrsq) : 0.;
1791 return CONST*tauErr;
1799 CLHEP::HepLorentzVector v1(V1.Px(),V1.Py(),V1.Pz(),V1.E());
1800 CLHEP::HepLorentzVector v2(V2.Px(),V2.Py(),V2.Pz(),V2.E());
1801 CLHEP::HepLorentzVector v0 = v1 + v2;
1802 CLHEP::Hep3Vector boost_v0 = v0.boostVector();
1804 v1.boost( boost_v0 );
1805 v2.boost( boost_v0 );
1806 theta = v0.angle( v1.vect() );
1814 CLHEP::HepLorentzVector posMom(PosMom.Px(),PosMom.Py(),PosMom.Pz(),PosMom.E());
1815 CLHEP::HepLorentzVector negMom(NegMom.Px(),NegMom.Py(),NegMom.Pz(),NegMom.E());
1821 CLHEP::HepLorentzVector v0(posTrack + negTrack);
1822 double Mv0 = v0.m();
1823 double Mplus = posTrack.m();
1824 double Mminus= negTrack.m();
1825 double Pv0 = v0.rho();
1826 double pssq = (Mv0*Mv0-(Mplus+Mminus)*(Mplus+Mminus))*(Mv0*Mv0-(Mplus-Mminus)*(Mplus-Mminus));
1827 double ps = (pssq>0.) ? sqrt(pssq) : 0.;
1829 double pp = v0.px()*posTrack.px() + v0.py()*posTrack.py() + v0.pz()*posTrack.pz();
1830 return ( v0.e()*pp - Pv0*Pv0*posTrack.e())/( Mv0*ps*Pv0);
1838 CLHEP::HepLorentzVector v_pos(V_pos.Px(),V_pos.Py(),V_pos.Pz(),V_pos.E());
1839 CLHEP::HepLorentzVector v_neg(V_neg.Px(),V_neg.Py(),V_neg.Pz(),V_neg.E());
1840 return phiStar(v_pos+v_neg,v_pos);
1843 double V0Tools::phiStar(
const CLHEP::HepLorentzVector & v0,
const CLHEP::HepLorentzVector & track)
1846 CLHEP::Hep3Vector V0 = v0.getV();
1847 CLHEP::Hep3Vector trk = track.getV();
1849 trk.rotateZ(-V0.phi());
1850 trk.rotateY(-V0.theta());
1857 phiStar = atan2(trk.y(),trk.x());
1864 auto vtx1 =
vtx(vxCandidate);
1866 return (mom.dot(vtx1))/(mom.mag()*(vtx1).
mag());
1872 auto vtx1 =
vtx(vxCandidate);
1873 vtx1 -=
vertex->position();
1874 return (mom.dot((vtx1)))/(mom.mag()*(vtx1).
mag());
1880 auto vtx1 =
vtx(vxCandidate);
1882 double pT = mom.perp();
1883 return (mom.x()*vtx1.x()+mom.y()*vtx1.y())/(
pT*vtx1.perp());
1889 auto vtx1 =
vtx(vxCandidate);
1890 vtx1 -=
vertex->position();
1891 double pT = mom.perp();
1892 return (mom.x()*vtx1.x()+mom.y()*vtx1.y())/(
pT*vtx1.perp());
1899 for(
unsigned int it=0; it<NTrk; it++) {
1918 if (NTrk != 2)
return origTrk;
1919 for(
unsigned int it=0; it<NTrk; it++) {
1929 if (NTrk != 2)
return origTrk;
1930 for(
unsigned int it=0; it<NTrk; it++) {
1938 double px = 0.,
py = 0.,
pz = 0., e = 0.;
1940 if (masses.size() != NTrk) {
1941 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
1944 for(
unsigned int it=0; it<NTrk; it++) {
1945 if (masses[it] >= 0.) {
1947 if (TP ==
nullptr)
return -999999.;
1948 TLorentzVector
Tp4 = TP->
p4();
1952 double pesq = 1./(TP->
qOverP()*TP->
qOverP()) + masses[it]*masses[it];
1953 double pe = (pesq>0.) ? sqrt(pesq) : 0.;
1958 return (msq>0.) ? sqrt(msq) : 0.;
1964 double px = 0.,
py = 0.,
pz = 0., e = 0.;
1966 if (masses.size() != NTrk) {
1967 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
1970 for(
unsigned int it=0; it<NTrk; it++) {
1971 if (masses[it] >= 0.) {
1973 if (TP ==
nullptr)
return -999999.;
1974 std::unique_ptr<const Trk::TrackParameters> extrPer =
1976 if (extrPer ==
nullptr)
1978 px += extrPer->momentum().x();
1979 py += extrPer->momentum().y();
1980 pz += extrPer->momentum().z();
1981 double pesq = extrPer->momentum().mag2() + masses[it]*masses[it];
1982 double pe = (pesq>0.) ? sqrt(pesq) : 0.;
1987 return (msq>0.) ? sqrt(msq) : 0.;
1994 double px = 0.,
py = 0.,
pz = 0., e = 0.;
1996 if (masses.size() != NTrk) {
1997 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
2000 for(
unsigned int it=0; it<NTrk; it++) {
2001 if (masses[it] >= 0.) {
2003 if (TP ==
nullptr)
return -999999.;
2004 std::unique_ptr<const Trk::TrackParameters> extrPer =
2006 if (extrPer ==
nullptr)
2008 px += extrPer->momentum().x();
2009 py += extrPer->momentum().y();
2010 pz += extrPer->momentum().z();
2011 double pesq = extrPer->momentum().mag2() + masses[it]*masses[it];
2012 double pe = (pesq>0.) ? sqrt(pesq) : 0.;
2017 return (msq>0.) ? sqrt(msq) : 0.;
2023 if (masses.size() != NTrk) {
2024 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
2028 double E=0., Px=0., Py=0., Pz=0.;
2030 std::vector<double>dm2dphi(NTrk), dm2dtheta(NTrk), dm2dqOverP(NTrk);
2032 for(
unsigned int it=0; it<NTrk; it++) {
2033 if (masses[it] >= 0.) {
2035 if (TP ==
nullptr)
return -999999.;
2037 V0_cor(5*it+2,5*it+2) = cov_tmp(2,2);
2038 V0_cor(5*it+2,5*it+3) = cov_tmp(2,3);
2039 V0_cor(5*it+2,5*it+4) = cov_tmp(2,4);
2040 V0_cor(5*it+3,5*it+3) = cov_tmp(3,3);
2041 V0_cor(5*it+3,5*it+4) = cov_tmp(3,4);
2042 V0_cor(5*it+4,5*it+4) = cov_tmp(4,4);
2043 V0_cor(5*it+3,5*it+2) = cov_tmp(2,3);
2044 V0_cor(5*it+4,5*it+2) = cov_tmp(2,4);
2045 V0_cor(5*it+4,5*it+3) = cov_tmp(3,4);
2050 double tmp = 1./(
qOverP[it]*
qOverP[it]) + masses[it]*masses[it];
2051 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
2054 TLorentzVector p4 = TP->
p4();
2061 for(
unsigned int it=0; it<NTrk; it++) {
2062 if (masses[it] >= 0.) {
2070 for(
unsigned int it=0; it<NTrk; it++) {
2071 D_vec(5*it+0,0) = 0.;
2072 D_vec(5*it+1,0) = 0.;
2073 D_vec(5*it+2,0) = dm2dphi[it];
2074 D_vec(5*it+3,0) = dm2dtheta[it];
2075 D_vec(5*it+4,0) = dm2dqOverP[it];
2077 Amg::MatrixX V0_merr = D_vec.transpose() * V0_cor * D_vec;
2079 double massVarsq = V0_merr(0,0);
2080 if (massVarsq <= 0.)
ATH_MSG_DEBUG(
"massError: negative sqrt massVarsq " << massVarsq);
2081 double massVar = (massVarsq>0.) ? sqrt(massVarsq) : 0.;
2082 double massErr = massVar/(2.*mass);
2090 if (masses.size() != NTrk) {
2091 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
2103 if (masses.size() != NTrk) {
2104 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
2108 double E=0., Px=0., Py=0., Pz=0.;
2110 std::vector<double>dm2dphi(NTrk), dm2dtheta(NTrk), dm2dqOverP(NTrk);
2112 for(
unsigned int it=0; it<NTrk; it++) {
2113 if (masses[it] >= 0.) {
2115 if (TP ==
nullptr)
return -999999.;
2116 std::unique_ptr<const Trk::TrackParameters> extrPer =
2118 if (extrPer ==
nullptr)
2120 const AmgSymMatrix(5)* cov_tmp = extrPer->covariance();
2121 V0_cor(5*it+2,5*it+2) = (*cov_tmp)(2,2);
2122 V0_cor(5*it+2,5*it+3) = (*cov_tmp)(2,3);
2123 V0_cor(5*it+2,5*it+4) = (*cov_tmp)(2,4);
2124 V0_cor(5*it+3,5*it+3) = (*cov_tmp)(3,3);
2125 V0_cor(5*it+3,5*it+4) = (*cov_tmp)(3,4);
2126 V0_cor(5*it+4,5*it+4) = (*cov_tmp)(4,4);
2127 V0_cor(5*it+3,5*it+2) = (*cov_tmp)(2,3);
2128 V0_cor(5*it+4,5*it+2) = (*cov_tmp)(2,4);
2129 V0_cor(5*it+4,5*it+3) = (*cov_tmp)(3,4);
2134 double tmp = 1./(
qOverP[it]*
qOverP[it]) + masses[it]*masses[it];
2135 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
2138 Px += extrPer->momentum().x();
2139 Py += extrPer->momentum().y();
2140 Pz += extrPer->momentum().z();
2143 double msq = E*E - Px*Px - Py*Py - Pz*Pz;
2144 double mass = (msq>0.) ? sqrt(msq) : 0.;
2146 for(
unsigned int it=0; it<NTrk; it++) {
2147 if (masses[it] >= 0.) {
2155 for(
unsigned int it=0; it<NTrk; it++) {
2156 D_vec(5*it+0,0) = 0.;
2157 D_vec(5*it+1,0) = 0.;
2158 D_vec(5*it+2,0) = dm2dphi[it];
2159 D_vec(5*it+3,0) = dm2dtheta[it];
2160 D_vec(5*it+4,0) = dm2dqOverP[it];
2162 Amg::MatrixX V0_merr = D_vec.transpose() * V0_cor * D_vec;
2164 double massVarsq = V0_merr(0,0);
2165 if (massVarsq <= 0.)
ATH_MSG_DEBUG(
"massError: negative sqrt massVarsq " << massVarsq);
2166 double massVar = (massVarsq>0.) ? sqrt(massVarsq) : 0.;
2167 double massErr = massVar/(2.*mass);
2176 if (masses.size() != NTrk) {
2177 ATH_MSG_DEBUG(
"The provided number of masses does not match the number of tracks in the vertex");
2181 double CONST = 1000./299.792;
2184 double dx = vert.x();
2185 double dy = vert.y();
2187 double E=0., Px=0., Py=0., Pz=0.;
2188 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
2189 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
2190 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk), dedqOverP(NTrk);
2191 std::vector<double>dMdqOverP(NTrk), dMdtheta(NTrk), dMdphi(NTrk);
2192 std::vector<double>dTaudqOverP(NTrk), dTaudtheta(NTrk), dTaudphi(NTrk);
2195 for(
unsigned int it=0; it<NTrk; it++) {
2197 double trkCharge = 1.;
2198 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
2202 double tmp = 1./(
qOverP*
qOverP) + masses[it]*masses[it];
2203 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
2218 double LXY = Px*dx+Py*dy;
2220 for(
unsigned int it=0; it<NTrk; it++) {
2221 dMdqOverP[it] = -(Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it]-E*dedqOverP[it])/M;
2222 dMdtheta[it] = -(Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/M;
2223 dMdphi[it] = -(Px*dpxdphi[it]+Py*dpydphi[it])/M;
2224 double dPTdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it])/PT;
2225 double dPTdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it])/PT;
2226 double dPTdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/PT;
2227 double dLXYdqOverP = dx*dpxdqOverP[it]+dy*dpydqOverP[it];
2228 double dLXYdtheta = dx*dpxdtheta[it]+dy*dpydtheta[it];
2229 double dLXYdphi = dx*dpxdphi[it]+dy*dpydphi[it];
2230 dTaudqOverP[it] = (LXY*dMdqOverP[it]+M*dLXYdqOverP)/(PT*PT)-(2.*LXY*M*dPTdqOverP)/(PT*PT*PT);
2231 dTaudtheta[it] = (LXY*dMdtheta[it]+M*dLXYdtheta)/(PT*PT)-(2.*LXY*M*dPTdtheta)/(PT*PT*PT);
2232 dTaudphi[it] = (LXY*dMdphi[it]+M*dLXYdphi)/(PT*PT)-(2.*LXY*M*dPTdphi)/(PT*PT*PT);
2234 double dTaudx = (M*Px)/(PT*PT);
2235 double dTaudy = (M*Py)/(PT*PT);
2236 double dTaudx0 = -dTaudx;
2237 double dTaudy0 = -dTaudy;
2239 unsigned int ndim = 0;
2240 if (fullCov.size() != 0) {
2241 ndim = fullCov.rows();
2247 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
2249 for(
unsigned int it=0; it<NTrk; it++) {
2250 D_mat(5*it+0,0) = 0.;
2251 D_mat(5*it+1,0) = 0.;
2252 D_mat(5*it+2,0) = CONST*dTaudphi[it];
2253 D_mat(5*it+3,0) = CONST*dTaudtheta[it];
2254 D_mat(5*it+4,0) = CONST*dTaudqOverP[it];
2255 D_mat(5*it+0,1) = 0.;
2256 D_mat(5*it+1,1) = 0.;
2257 D_mat(5*it+2,1) = dMdphi[it];
2258 D_mat(5*it+3,1) = dMdtheta[it];
2259 D_mat(5*it+4,1) = dMdqOverP[it];
2261 D_mat(5*NTrk+0,0) = CONST*dTaudx;
2262 D_mat(5*NTrk+1,0) = CONST*dTaudy;
2263 D_mat(5*NTrk+2,0) = 0.;
2264 D_mat(5*NTrk+3,0) = CONST*dTaudx0;
2265 D_mat(5*NTrk+4,0) = CONST*dTaudy0;
2266 D_mat(5*NTrk+5,0) = 0.;
2267 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
2268 if (fullCov.size() != 0) {
2269 W_mat.block(0,0,ndim,ndim) = fullCov;
2272 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
2273 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
2275 W_mat.block<3,3>(5*NTrk+3,5*NTrk+3) =
vertex->covariancePosition();
2276 V0_err = D_mat.transpose() * W_mat * D_mat;
2277 }
else if (ndim == 3*NTrk+3) {
2279 D_mat(0,0) = CONST*dTaudx;
2280 D_mat(1,0) = CONST*dTaudy;
2282 for(
unsigned int it=0; it<NTrk; it++) {
2283 D_mat(3*it+3,0) = CONST*dTaudphi[it];
2284 D_mat(3*it+4,0) = CONST*dTaudtheta[it];
2285 D_mat(3*it+5,0) = CONST*dTaudqOverP[it];
2286 D_mat(3*it+3,1) = dMdphi[it];
2287 D_mat(3*it+4,1) = dMdtheta[it];
2288 D_mat(3*it+5,1) = dMdqOverP[it];
2290 D_mat(3*NTrk+3,0) = CONST*dTaudx0;
2291 D_mat(3*NTrk+4,0) = CONST*dTaudy0;
2292 D_mat(3*NTrk+5,0) = 0.;
2293 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
2294 W_mat.block(0,0,ndim,ndim) = fullCov;
2295 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
2296 V0_err = D_mat.transpose() * W_mat * D_mat;
2307 for(
unsigned int it=0; it<NTrk; it++){
2310 V0_cov(5*it+2,5*it+2) = (*cov_tmp)(2,2);
2311 V0_cov(5*it+2,5*it+3) = (*cov_tmp)(2,3);
2312 V0_cov(5*it+2,5*it+4) = (*cov_tmp)(2,4);
2313 V0_cov(5*it+3,5*it+3) = (*cov_tmp)(3,3);
2314 V0_cov(5*it+3,5*it+4) = (*cov_tmp)(3,4);
2315 V0_cov(5*it+4,5*it+4) = (*cov_tmp)(4,4);
2316 V0_cov(5*it+3,5*it+2) = (*cov_tmp)(2,3);
2317 V0_cov(5*it+4,5*it+2) = (*cov_tmp)(2,4);
2318 V0_cov(5*it+4,5*it+3) = (*cov_tmp)(3,4);
2328 if (masses.size() != NTrk) {
2329 ATH_MSG_ERROR(
"The provided number of masses does not match the number of tracks in the vertex");
2333 double CONST = 1000./299.792;
2336 double dx = vert.x();
2337 double dy = vert.y();
2339 double E=0., Px=0., Py=0., Pz=0.;
2340 std::vector<double>dpxdqOverP(NTrk), dpxdtheta(NTrk), dpxdphi(NTrk);
2341 std::vector<double>dpydqOverP(NTrk), dpydtheta(NTrk), dpydphi(NTrk);
2342 std::vector<double>dpzdqOverP(NTrk), dpzdtheta(NTrk), dedqOverP(NTrk);
2343 std::vector<double>dMdqOverP(NTrk), dMdtheta(NTrk), dMdphi(NTrk);
2344 std::vector<double>dTaudqOverP(NTrk), dTaudtheta(NTrk), dTaudphi(NTrk);
2347 for(
unsigned int it=0; it<NTrk; it++) {
2349 double trkCharge = 1.;
2350 if (bPer->parameters()[
Trk::qOverP] < 0.) trkCharge = -1.;
2354 double tmp = 1./(
qOverP*
qOverP) + masses[it]*masses[it];
2355 double pe = (tmp>0.) ? sqrt(tmp) : 0.;
2370 double LXY = Px*dx+Py*dy;
2372 for(
unsigned int it=0; it<NTrk; it++) {
2373 dMdqOverP[it] = -(Px*dpxdqOverP[it]+Py*dpydqOverP[it]+Pz*dpzdqOverP[it]-E*dedqOverP[it])/M;
2374 dMdtheta[it] = -(Px*dpxdtheta[it]+Py*dpydtheta[it]+Pz*dpzdtheta[it])/M;
2375 dMdphi[it] = -(Px*dpxdphi[it]+Py*dpydphi[it])/M;
2376 double dPTdqOverP = (Px*dpxdqOverP[it]+Py*dpydqOverP[it])/PT;
2377 double dPTdtheta = (Px*dpxdtheta[it]+Py*dpydtheta[it])/PT;
2378 double dPTdphi = (Px*dpxdphi[it]+Py*dpydphi[it])/PT;
2379 double dLXYdqOverP = dx*dpxdqOverP[it]+dy*dpydqOverP[it];
2380 double dLXYdtheta = dx*dpxdtheta[it]+dy*dpydtheta[it];
2381 double dLXYdphi = dx*dpxdphi[it]+dy*dpydphi[it];
2382 dTaudqOverP[it] = (LXY*dMdqOverP[it]+M*dLXYdqOverP)/(PT*PT)-(2.*LXY*M*dPTdqOverP)/(PT*PT*PT);
2383 dTaudtheta[it] = (LXY*dMdtheta[it]+M*dLXYdtheta)/(PT*PT)-(2.*LXY*M*dPTdtheta)/(PT*PT*PT);
2384 dTaudphi[it] = (LXY*dMdphi[it]+M*dLXYdphi)/(PT*PT)-(2.*LXY*M*dPTdphi)/(PT*PT*PT);
2386 double dTaudx = (M*Px)/(PT*PT);
2387 double dTaudy = (M*Py)/(PT*PT);
2388 double dTaudx0 = -dTaudx;
2389 double dTaudy0 = -dTaudy;
2391 unsigned int ndim = 0;
2392 if (fullCov.size() != 0) {
2393 ndim = fullCov.rows();
2398 if (ndim == 5*NTrk+3 || ndim == 5*NTrk+6) {
2400 for(
unsigned int it=0; it<NTrk; it++) {
2401 D_mat(5*it+0,0) = 0.;
2402 D_mat(5*it+1,0) = 0.;
2403 D_mat(5*it+2,0) = CONST*dTaudphi[it];
2404 D_mat(5*it+3,0) = CONST*dTaudtheta[it];
2405 D_mat(5*it+4,0) = CONST*dTaudqOverP[it];
2406 D_mat(5*it+0,1) = 0.;
2407 D_mat(5*it+1,1) = 0.;
2408 D_mat(5*it+2,1) = dMdphi[it];
2409 D_mat(5*it+3,1) = dMdtheta[it];
2410 D_mat(5*it+4,1) = dMdqOverP[it];
2412 D_mat(5*NTrk+0,0) = CONST*dTaudx;
2413 D_mat(5*NTrk+1,0) = CONST*dTaudy;
2414 D_mat(5*NTrk+2,0) = 0.;
2415 D_mat(5*NTrk+3,0) = CONST*dTaudx0;
2416 D_mat(5*NTrk+4,0) = CONST*dTaudy0;
2417 D_mat(5*NTrk+5,0) = 0.;
2418 Amg::MatrixX W_mat(5*NTrk+6,5*NTrk+6); W_mat.setZero();
2419 if (fullCov.size() != 0) {
2420 W_mat.block(0,0,ndim,ndim) = fullCov;
2423 W_mat.block(0,0,V0_cov.rows(),V0_cov.rows()) = V0_cov;
2424 W_mat.block<3,3>(5*NTrk,5*NTrk) = vxCandidate->covariancePosition();
2426 W_mat.block<3,3>(5*NTrk+3,5*NTrk) =
vertex->covariancePosition();
2427 V0_err = D_mat.transpose() * W_mat * D_mat;
2428 }
else if (ndim == 3*NTrk+3) {
2430 D_mat(0,0) = CONST*dTaudx;
2431 D_mat(1,0) = CONST*dTaudy;
2433 for(
unsigned int it=0; it<NTrk; it++) {
2434 D_mat(3*it+3,0) = CONST*dTaudphi[it];
2435 D_mat(3*it+4,0) = CONST*dTaudtheta[it];
2436 D_mat(3*it+5,0) = CONST*dTaudqOverP[it];
2437 D_mat(3*it+3,1) = dMdphi[it];
2438 D_mat(3*it+4,1) = dMdtheta[it];
2439 D_mat(3*it+5,1) = dMdqOverP[it];
2441 D_mat(3*NTrk+3,0) = CONST*dTaudx0;
2442 D_mat(3*NTrk+4,0) = CONST*dTaudy0;
2443 D_mat(3*NTrk+5,0) = 0.;
2444 Amg::MatrixX W_mat(3*NTrk+6,3*NTrk+6); W_mat.setZero();
2445 W_mat.block(0,0,ndim,ndim) = fullCov;
2446 W_mat.block<3,3>(3*NTrk+3,3*NTrk+3) =
vertex->covariancePosition();
2447 V0_err = D_mat.transpose() * W_mat * D_mat;
2458 const std::vector<float> &matrix = vxCandidate->
covariance();
2462 if ( matrix.size() == (3*NTrk+3)*(3*NTrk+3+1)/2) {
2464 }
else if (matrix.size() == (5*NTrk+3)*(5*NTrk+3+1)/2) {
2473 for (
int i=1; i<= ndim; i++) {
2474 for (
int j=1; j<=i; j++){
2476 mtx(i-1,j-1)=matrix[ij];
2478 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.