10 const float rCyl,
const float yCyl,
const float zCyl,
float* retXYZ1,
float* retXYZ2,
11 const float Xmax,
const float epsilon)
15 const float y0 = trackpar[0];
16 const float z0 = trackpar[1];
17 const float curv = trackpar[2];
18 const float phi0 = trackpar[3];
19 const float tanl = std::tan(trackpar[4]);
30 float zL[2];
float yL[2];
31 zL[0] = zCyl -rCyl -1.0; zL[1] = zCyl +rCyl +1.0;
32 for (
int i=0; i<2; ++i) yL[i] = y0 +(zL[i] -z0)*std::tan(phi0);
34 float Dx = zL[1] -zL[0];
float Dy = yL[1] -yL[0];
35 float Dr =
std::hypot(Dx,Dy);
float D = zL[0]*yL[1] -zL[1]*yL[0];
36 float det = (rCyl*Dr)*(rCyl*Dr) - D*
D;
39 float zz1 = (D*Dy +Dx*det) / (Dr*Dr);
40 float zz2 = (D*Dy -Dx*det) / (Dr*Dr);
41 float yy1 = y0 +(zz1 -z0)*std::tan(phi0);
42 float yy2 = y0 +(zz2 -z0)*std::tan(phi0);
54 retXYZ1[0] = ( retXYZ1[2]-z0 ) / std::cos(phi0);
55 retXYZ2[0] = ( retXYZ2[2]-z0 ) / std::cos(phi0);
61 float zcc = z0 - radius * std::sin(phi0);
62 float ycc = y0 + radius * std::cos(phi0);
66 float dz = zcc - zCyl;
67 float dy = ycc - yCyl;
73 if ( d > (rCyl +
abs(radius)) ) {
77 if (d < std::fabs(rCyl -
abs(radius))) {
87 float phiStar = (d*d + rCyl*rCyl - radius*radius);
89 if (phiStar > +1.
f) phiStar = +0.9999999f;
90 if (phiStar < -1.
f) phiStar = -0.9999999f;
91 phiStar = std::acos(phiStar);
93 float phiCentre(std::atan2(dy, dz));
97 float zz1 = zCyl + rCyl * std::cos(phiCentre + phiStar);
98 float yy1 = yCyl + rCyl * std::sin(phiCentre + phiStar);
100 float phi1 = atan2( yy1-ycc, zz1-zcc );
101 phi1 += (curv>=0) ?
M_PI/2.0 : 3.0*
M_PI/2.0;
102 float zz2 = zCyl + rCyl * std::cos(phiCentre - phiStar);
103 float yy2 = yCyl + rCyl * std::sin(phiCentre - phiStar);
104 float phi2 = atan2( yy2-ycc, zz2-zcc );
105 phi2 += (curv>=0) ?
M_PI/2.0 : 3.0*
M_PI/2.0;
107 float dphi1 = phi1 -phi0;
108 float dphi2 = phi2 -phi0;
109 int nturns = dphi1/(2.0*
M_PI);
111 if (dphi1 > +(2.0*
M_PI)) dphi1 -= (2.0*
M_PI)*nturns;
112 if (dphi1 < -(2.0*
M_PI)) dphi1 += (2.0*
M_PI)*nturns;
113 if (dphi1 > +
M_PI) dphi1 -= 2.0*
M_PI;
114 if (dphi1 < -
M_PI) dphi1 += 2.0*
M_PI;
116 nturns = dphi2/(2.0*
M_PI);
117 if (dphi2 > +(2.0*
M_PI)) dphi2 -= (2.0*
M_PI)*nturns;
118 if (dphi2 < -(2.0*
M_PI)) dphi2 += (2.0*
M_PI)*nturns;
119 if (dphi2 > +
M_PI) dphi2 -= 2.0*
M_PI;
120 if (dphi2 < -
M_PI) dphi2 += 2.0*
M_PI;
121 if ( fabs(dphi1) < fabs(dphi2) ) {
124 retXYZ1[0] = Xpoint[0] + radius * tanl * dphi1;
127 retXYZ2[0] = Xpoint[0] + radius * tanl * dphi2;
132 retXYZ1[0] = Xpoint[0] + radius * tanl * dphi2;
135 retXYZ2[0] = Xpoint[0] + radius * tanl * dphi1;
140 if ( std::fabs(Xmax) > 0 ) {
141 if ( std::fabs(retXYZ1[0]) > std::fabs(Xmax) ) {
145 if ( std::fabs(retXYZ2[0]) > std::fabs(Xmax) ) {
158 const float x,
float* retXYZ,
const float Rmax)
163 const float y0 = trackpar[0];
164 const float z0 = trackpar[1];
165 const float phi0 = trackpar[3];
166 const float curv = trackpar[2];
168 if (curv != 0) radius = 1.0 / curv;
170 float ZCent = trackpar[1] - radius*std::sin(phi0);
171 float YCent = trackpar[0] + radius*std::cos(phi0);
172 float tanl = std::tan(trackpar[4]);
178 float dT = (x -Xpoint[0]) / tanl;
179 y = y0 +dT*std::sin(phi0);
180 z = z0 +dT*std::cos(phi0);
191 float phi = (x - Xpoint[0]) * s / radius + phi0;
192 y = YCent - radius * std::cos(phi);
193 z = ZCent + radius * std::sin(phi);
200 retXYZ[0] =
x; retXYZ[1] =
y; retXYZ[2] =
z;
209 const float* xyz,
float& retDist) {
218 float x0 = Xpoint[0];
219 float y0 = trackpar[0];
220 float z0 = trackpar[1];
221 float curv = trackpar[2];
223 float phi0 = trackpar[3];
225 float s = std::tan(trackpar[4]);
232 float sinphi0 = std::sin(phi0);
233 float cosphi0 = std::cos(phi0);
234 float zc = trackpar[1] - r * sinphi0;
235 float yc = trackpar[0] + r * cosphi0;
242 float h = std::sqrt(1.0 + s*s);
243 float xhc = s*(yt-y0)*(cosphi0/h) - s*(sinphi0/
h)*(zt-z0);
244 float yhc = (zt-z0)/h - s*(xt-x0)*(cosphi0/
h);
245 float zhc = s*(xt-x0)*(sinphi0/h) - (yt-y0)/h;
247 retDist = std::sqrt( xhc*xhc + yhc*yhc + zhc*zhc );
253 retDist = std::sqrt( TMath::Sq(yt-y0) + TMath::Sq(zt-z0) );
259 float gold = 1.61803398875;
263 float phicent = (s*curv)*(xt-x0) +phi0;
264 float d2cent =
d2(xt,yt,zt, x0,yc,zc, r,s, phicent, phi0);
265 float philow = phicent -
span;
266 float d2low =
d2(xt,yt,zt, x0,yc,zc, r,s, philow, phi0);
267 float phihi = phicent +
span;
268 float d2hi =
d2(xt,yt,zt, x0,yc,zc, r,s, phihi, phi0);
269 if ( d2low<d2cent ) {
272 if ( std::fabs(philow -phi0) < std::fabs(phihi -phi0) ) {
277 philow = phicent -
span;
278 phihi = phicent +
span;
284 for (
size_t iter=0; iter<18; ++iter) {
286 float B = (d2hi -d2low) / (2*span);
287 float A = (d2hi +d2low -2*d2cent) / ( 2*span*span );
289 phicent += -B / (2*
A);
291 philow = phicent -
span;
292 phihi = phicent +
span;
293 d2cent =
d2(xt,yt,zt, x0,yc,zc, r,s, phicent, phi0);
294 d2low =
d2(xt,yt,zt, x0,yc,zc, r,s, philow, phi0);
295 d2hi =
d2(xt,yt,zt, x0,yc,zc, r,s, phihi, phi0);
298 float xp = x0 + r*(phicent -phi0)/s;
299 float yp = yc - r*TMath::Cos(phicent);
300 float zp = zc + r*TMath::Sin(phicent);
301 retDist = std::sqrt(TMath::Sq(xt-xp) +TMath::Sq(yt-yp) +TMath::Sq(zt-zp));
310 float& xEval,
float* retXYZ) {
312 if (trackpar[2]==0)
return 1;
313 float r = 1.0/trackpar[2];
314 float s = std::tan(trackpar[4]);
315 float x0 = Xpoint[0];
317 float phi = (xEval -x0)/(r*s);
325 float& phiEval,
float* retXYZ) {
327 retXYZ[0] = std::tan(trackpar[4]);
328 retXYZ[1] = std::sin(phiEval);
329 retXYZ[2] = std::cos(phiEval);
331 for (
int i=0; i<3; ++i) retXYZ[i] /= norm;
340 float x0,
float yc,
float zc,
float r,
float s,
float phi,
float phi0)
342 float dx = (xt -x0) - (r/s)*(phi -phi0);
343 float dy = (yt -yc) + r*TMath::Cos(phi);
344 float dz = (zt -zc) - r*TMath::Sin(phi);
345 return dx*dx + dy*dy + dz*dz;
span(IterB &&b, IterE &&e, Adaptor &&adaptor) -> span< decltype(adaptor(std::forward< IterB >(b))), decltype(adaptor(std::forward< IterE >(e))) >
Namespace for general, non-LArSoft-specific utilities.
static int DistXYZ(const float *trackpar, const float *Xpoint, const float *xyz, float &retDist)
constexpr auto abs(T v)
Returns the absolute value of the argument.
Simple class with a begin and an end.
std::enable_if_t< std::is_arithmetic_v< T >, T > hypot(T x, T y)
static int PropagateToX(const float *trackpar, const float *Xpoint, const float x, float *retXYZ, const float Rmax=0.0)
static int PropagateToCylinder(const float *trackpar, const float *Xpoint, const float rCyl, const float yCyl, const float zCyl, float *retXYZ1, float *retXYZ2, const float Xmax=0.0, const float epsilon=2.0e-5)
static int max(int a, int b)
auto norm(Vector const &v)
Return norm of the specified vector.
Interface to propagate a Track to the specific point.
static int DirectionPhi(const float *trackpar, const float *Xpoint, float &phiEval, float *retXYZ)
static int DirectionX(const float *trackpar, const float *Xpoint, float &xEval, float *retXYZ)
static float d2(float xt, float yt, float zt, float x0, float yc, float zc, float r, float s, float phi, float phi0)