14 inline double getRadiusOfCurvature(
const Trk::Perigee & myPerigee,
const double Bzfield) {
29 declareInterface<TrkDistanceFinderNeutralCharged>(
this);
36 std::pair<Amg::Vector3D,double>
39 double & distanceOnAxis,
42 double b_phi0=chargedtrk.parameters()[
Trk::phi0];
43 double b_cosphi0=
cos(b_phi0);
44 double b_sinphi0=
sin(b_phi0);
46 chargedtrk.parameters()[
Trk::d0]*b_sinphi0;
48 chargedtrk.parameters()[
Trk::d0]*b_cosphi0;
50 chargedtrk.parameters()[
Trk::z0];
56 double Bz=magnFieldVect.z()*299.792;
58 double b_Rt=getRadiusOfCurvature(chargedtrk,Bz);
60 double b_cottheta=1./
tan(chargedtrk.parameters()[
Trk::theta]);
63 double a_x0=neutraltrk.
position()[0];
64 double a_y0=neutraltrk.
position()[1];
65 double a_z0=neutraltrk.
position()[2];
66 double a_px=neutraltrk.
momentum()[0];
67 double a_py=neutraltrk.
momentum()[1];
68 double a_pz=neutraltrk.
momentum()[2];
72 double DxNoVar=b_x0+b_Rt*b_sinphi0-a_x0;
73 double DyNoVar=b_y0-b_Rt*b_cosphi0-a_y0;
74 double DzNoVar=b_z0+b_Rt*b_cottheta*b_phi0-a_z0;
78 double b_cosphi=
cos(b_phi);
79 double b_sinphi=
sin(b_phi);
83 double deltaa_lambda=0.;
89 bool secondTimeSaddleProblem=
false;
98 double x1fin=b_x0+b_Rt*(
sin(b_phi0)-
sin(b_phi));
99 double y1fin=b_y0+b_Rt*(
cos(b_phi)-
cos(b_phi0));
100 double z1fin=b_z0+b_Rt*b_cottheta*(b_phi0-b_phi);
102 double x2fin=a_x0+a_px*a_lambda;
103 double y2fin=a_y0+a_py*a_lambda;
104 double z2fin=a_z0+a_pz*a_lambda;
106 ATH_MSG_VERBOSE (
"x1fin " << x1fin <<
"y1fin " << y1fin <<
"z1fin " << z1fin);
107 ATH_MSG_VERBOSE (
"x2fin " << x2fin <<
"y2fin " << y2fin <<
"z2fin " << z2fin);
109 double distance = sqrt((x1fin-x2fin)*(x1fin-x2fin)+
110 (y1fin-y2fin)*(y1fin-y2fin)+
111 (z1fin-z2fin)*(z1fin-z2fin));
119 double d1db_phi=((DxNoVar-a_px*a_lambda)*(-b_Rt*b_cosphi)+
120 (DyNoVar-a_py*a_lambda)*(-b_Rt*b_sinphi)+
121 (DzNoVar-b_Rt*b_phi*b_cottheta-a_pz*a_lambda)*(-b_Rt*b_cottheta));
123 double d1da_lambda=((DxNoVar-b_Rt*b_sinphi-a_px*a_lambda)*(-a_px)+
124 (DyNoVar+b_Rt*b_cosphi-a_py*a_lambda)*(-a_py)+
125 (DzNoVar-b_Rt*b_cottheta*b_phi-a_pz*a_lambda)*(-a_pz));
129 double d2db_phi2=((DxNoVar-a_px*a_lambda)*(b_Rt*b_sinphi)+
130 (DyNoVar-a_py*a_lambda)*(-b_Rt*b_cosphi)+
131 (b_Rt*b_cottheta*b_Rt*b_cottheta));
133 double d2dadb_lambdaphi=a_px*b_Rt*b_cosphi+a_py*b_Rt*b_sinphi+a_pz*b_Rt*b_cottheta;
141 double d2da_lambda2=((a_px*a_px)+
146 ATH_MSG_VERBOSE (
" d1db_phi: " << d1db_phi <<
" d1da_lambda " << d1da_lambda);
148 ATH_MSG_VERBOSE (
" d2phi2 " << d2db_phi2 <<
" d2lambda2 " <<d2da_lambda2 <<
149 " d2lambdaphi " << d2dadb_lambdaphi);
152 double det=d2da_lambda2*d2db_phi2-d2dadb_lambdaphi*d2dadb_lambdaphi;
155 if (!secondTimeSaddleProblem)
157 secondTimeSaddleProblem=
true;
161 double firstTerm=(DxNoVar*a_px+DyNoVar*a_py)*
denominator;
162 double toSquare=(a_px*DyNoVar-a_py*DxNoVar);
163 double toSqrt=b_Rt*b_Rt/
denominator-toSquare*toSquare;
166 ATH_MSG_WARNING (
"No intersection between neutral and charged track can be found. SKipping...");
171 double lambda1=firstTerm+secondTerm;
172 double lambda2=firstTerm-secondTerm;
174 ATH_MSG_VERBOSE (
"first solution: " << lambda1 <<
" second solution " << lambda2);
176 double phi1=
TMath::ATan2((DxNoVar-a_px*lambda1)/b_Rt,-(DyNoVar-a_py*lambda1)/b_Rt);
177 double phi2=
TMath::ATan2((DxNoVar-a_px*lambda2)/b_Rt,-(DyNoVar-a_py*lambda2)/b_Rt);
179 double x1case1=b_x0+b_Rt*(
sin(b_phi0)-
sin(phi1));
180 double y1case1=b_y0+b_Rt*(
cos(phi1)-
cos(b_phi0));
181 double z1case1=b_z0+b_Rt*b_cottheta*(b_phi0-phi1);
183 double x2case1=a_x0+a_px*lambda1;
184 double y2case1=a_y0+a_py*lambda1;
185 double z2case1=a_z0+a_pz*lambda1;
187 double x1case2=b_x0+b_Rt*(
sin(b_phi0)-
sin(phi2));
188 double y1case2=b_y0+b_Rt*(
cos(phi2)-
cos(b_phi0));
189 double z1case2=b_z0+b_Rt*b_cottheta*(b_phi0-phi2);
191 double x2case2=a_x0+a_px*lambda2;
192 double y2case2=a_y0+a_py*lambda2;
193 double z2case2=a_z0+a_pz*lambda2;
195 ATH_MSG_VERBOSE (
"solution1 x1: " << x1case1 <<
" x2: " << x2case1 <<
" y1: " << y1case1 <<
" y2: " << y2case1);
196 ATH_MSG_VERBOSE (
"solution2 x1: " << x1case2 <<
" x2: " << x2case2 <<
" y1: " << y1case2 <<
" y2: " << y2case2);
198 double deltaz1=fabs(z2case1-z1case1);
199 double deltaz2=fabs(z2case2-z1case2);
203 if (deltaz1<=deltaz2)
224 if (
det>0&&d2da_lambda2<0) {
225 ATH_MSG_WARNING(
"Hessian indicates a maximum: derivative will be zero but result incorrect");
230 deltaa_lambda=-(d2db_phi2*d1da_lambda-d2dadb_lambdaphi*d1db_phi)/
det;
231 deltab_phi=-(-d2dadb_lambdaphi*d1da_lambda+d2da_lambda2*d1db_phi)/
det;
233 a_lambda+=deltaa_lambda;
247 double x1fin=b_x0+b_Rt*(
sin(b_phi0)-
sin(b_phi));
248 double y1fin=b_y0+b_Rt*(
cos(b_phi)-
cos(b_phi0));
249 double z1fin=b_z0+b_Rt*b_cottheta*(b_phi0-b_phi);
251 double x2fin=a_x0+a_px*a_lambda;
252 double y2fin=a_y0+a_py*a_lambda;
253 double z2fin=a_z0+a_pz*a_lambda;
255 ATH_MSG_VERBOSE (
"x1fin " << x1fin <<
"y1fin " << y1fin <<
"z1fin " << z1fin);
256 ATH_MSG_VERBOSE (
"x2fin " << x2fin <<
"y2fin " << y2fin <<
"z2fin " << z2fin);
258 double distance = sqrt((x1fin-x2fin)*(x1fin-x2fin)+
259 (y1fin-y2fin)*(y1fin-y2fin)+
260 (z1fin-z2fin)*(z1fin-z2fin));
263 <<
"fitted dist from primary vertex " <<
264 a_lambda/fabs(a_lambda)*sqrt(
std::pow(a_px*a_lambda,2)+
267 distanceOnAxis=a_lambda/fabs(a_lambda)*sqrt(
std::pow(a_px*a_lambda,2)+
274 return std::pair<Amg::Vector3D,double>(r2,
distance);