CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ThirdHitPredictionFromCircle.cc
Go to the documentation of this file.
1 #include <cmath>
4 
7 
10 
11 // there are tons of safety checks.
12 // Try to move all of the out the regular control flow using gcc magic
13 
14 
15 namespace {
16  template<class T> inline T sqr(T t) { return t * t; }
17  template<class T> inline T sgn(T t) { return std::signbit(t) ? -T(1.) : T(1.); }
18  template<class T> inline T clamped_acos(T t)
19  { return unlikely(t <= T(-1)) ? T(M_PI) : unlikely(t >= T(1)) ? T(0) : std::acos(t); }
20  template<class T> inline T clamped_sqrt(T t)
21  { return likely(t > 0) ? std::sqrt(t) : T(0); }
22 }
23 
25  const GlobalPoint& P1, const GlobalPoint& P2, float tolerance)
26  : p1(P1.x(), P1.y()), theTolerance(tolerance)
27 {
28  Vector2D p2(P2.x(), P2.y());
29  Vector2D diff = 0.5 * (p2 - p1);
30  delta2 = diff.mag2();
32  axis = Vector2D(-diff.y(), diff.x()) / delta;
33  center = p1 + diff;
34 }
35 
37 {
38  float phi;
39  if (unlikely(std::abs(curvature) < float(1.0e-5))) {
40  float cos = (center * axis) / radius;
41  phi = axis.phi() - clamped_acos(cos);
42  } else {
43  float sign = sgn(curvature);
44  float radius2 = sqr(1.0f / curvature);
45  float orthog = clamped_sqrt(radius2 - delta2);
47  float rc2 = lcenter.mag2();
48  float cos = (rc2 + sqr(radius) - radius2) /
49  (2.f *std:: sqrt(rc2) * radius);
50  phi = lcenter.barePhi() + sign * clamped_acos(cos);
51  }
52 
53  while(unlikely(phi >= float(M_PI))) phi -= float(2. * M_PI);
54  while(unlikely(phi < -float(M_PI))) phi += float(2. * M_PI);
55 
56  return phi;
57 }
58 
60 {
61  if (unlikely(std::abs(curvature) < float(1.0e-5))) {
62  float sin = (center * axis) / radius;
63  return sin / clamped_sqrt(1 - sqr(sin));
64  } else {
65  float radius2 = sqr(1.0f / curvature);
66  float orthog = clamped_sqrt(radius2 - delta2);
68 
69  float cos = (radius2 + sqr(radius) - lcenter.mag2()) *
70  curvature / (2 * radius);
71  return - cos / clamped_sqrt(1.f - sqr(cos));
72  }
73 }
74 
77 {
78  float phi1 = phi(curvature.second, radius);
79  float phi2 = phi(curvature.first, radius);
80 
81  while(unlikely(phi2 < phi1)) phi2 += float(2. * M_PI);
82 
83  return Range(phi1 * radius - theTolerance, phi2 * radius + theTolerance);
84 }
85 
87 ThirdHitPredictionFromCircle::curvature(double transverseIP) const
88 {
89  // this is a mess. Use a CAS and lots of drawings to verify...
90 
91  transverseIP = std::abs(transverseIP);
92  double transverseIP2 = sqr(transverseIP);
93  double tip = axis * center;
94  double tip2 = sqr(tip);
95  double lip = axis.x() * center.y() - axis.y() * center.x();
96  double lip2 = sqr(lip);
97 
98  double origin = std::sqrt(tip2 + lip2);
99  double tmp1 = lip2 + tip2 - transverseIP2;
100  double tmp2 = 2. * (tip - transverseIP) * (tip + transverseIP);
101  double tmp3 = 2. * delta * origin;
102  double tmp4 = tmp1 + delta2;
103  double tmp5 = 2. * delta * lip;
104 
105  // I am probably being overly careful here with border cases
106  // but you never know what crap you might get fed
107  // VI fixed for finiteMath
108 
109  double u1=0, u2=0;
110  constexpr double SMALL = 1.0e-23;
111  constexpr double LARGE = 1.0e23;
112 
113  if (unlikely(tmp4 - tmp5 < 1.0e-15)) {
114  u1 = -SMALL;
115  u2 = +SMALL;
116  } else {
117  if (unlikely(std::abs(tmp2) < 1.0e-15)) {
118  // the denominator is zero
119  // this means that one of the tracks will be straight
120  // and the other can be computed from the limit of the equation
121  double tmp = lip2 - delta2;
122  u1 = LARGE;
123  u2 = (sqr(0.5 * tmp) - delta2 * tip2) / (tmp * tip);
124  if (tip < 0)
125  std::swap(u1, u2);
126  } else {
127  double tmp6 = (tmp4 - tmp5) * (tmp4 + tmp5);
128  if (unlikely(tmp6 < 1.0e-15)) {
129  u1 = -SMALL;
130  u2 = +SMALL;
131  } else {
132  double tmp7 = tmp6 > 0 ? (transverseIP * std::sqrt(tmp6) / tmp2) : 0.;
133  double tmp8 = tip * (tmp1 - delta2) / tmp2;
134  // the two quadratic solutions
135  u1 = tmp8 + tmp7;
136  u2 = tmp8 - tmp7;
137  }
138  }
139 
140  if (tmp4 <= std::abs(tmp3)) {
141  if ((tmp3 < 0) == (tip < 0))
142  u2 = +SMALL;
143  else
144  u1 = -SMALL;
145  }
146  }
147 
148  return Range(sgn(u1) / std::sqrt(sqr(u1) + delta2),
149  sgn(u2) / std::sqrt(sqr(u2) + delta2));
150 }
151 
154 {
155  Vector2D del = p2 - p1;
156  Vector2D axis2 = Vector2D(-del.y(), del.x()) / del.mag();
157  Vector2D diff = p1 + 0.5f * del - center;
158  Scalar a = diff.y() * axis2.x() - diff.x() * axis2.y();
159  Scalar b = axis.y() * axis2.x() - axis.x() * axis2.y();
160  return b / a;
161 }
162 
164 {
165  double invDist = invCenterOnAxis(p2);
166  double invDist2 = sqr(invDist);
167  double curv = std::sqrt(invDist2 / (1. + invDist2 * delta2));
168  return sgn(invDist) * curv;
169 }
170 
172 {
173  double invDist = invCenterOnAxis(p2);
174  if (unlikely(std::abs(invDist) < 1.0e-5))
175  return std::abs(p2 * axis);
176  else {
177  double dist = 1.0 / invDist;
178  double radius = std::sqrt(sqr(dist) + delta2);
179  return std::abs((center + axis * dist).mag() - radius);
180  }
181 }
182 
183 //------------------------------------------------------------------------------
184 
186  const ThirdHitPredictionFromCircle * icircle, double iz1, double z2, double curv) :
187  circle(icircle), curvature(curv), radius(1./curv), z1(iz1)
188 {
189  Scalar orthog = sgn(curv) * clamped_sqrt(radius*radius - circle->delta2);
190  center = circle->center + orthog * circle->axis;
191 
192  Scalar absCurv = std::abs(curv);
193  seg = circle->delta;
194 
195  if (likely(absCurv > 1.0e-5)) {
196  seg *= absCurv;
197  seg = seg < -1.0 ? -M_PI_2 : seg > 1.0 ? M_PI_2 : std::asin(seg);
198  seg /= absCurv;
199  }
200 
201  seg *= 2.;
202  dzdu = likely(std::abs(seg) > 1.0e-5) ? ((z2 - z1) / seg) : 99999.0;
203 }
204 
206  const ThirdHitPredictionFromCircle *circle, double z1, double z2, double z3)
207 {
208  constexpr double maxAngle = M_PI;
209  double halfAngle = (0.5 * maxAngle) * (z2 - z1) / (z3 - z1);
210  if (unlikely(halfAngle <= 0.0))
211  return 0.0;
212 
213  return std::sin(halfAngle) / circle->delta;
214 }
215 
216 
219  if (unlikely(std::abs(curvature) < 1.0e-5)) {
220  Scalar tip = circle->axis * circle->p1;
221  Scalar lip = circle->axis.y() * circle->p1.x() -
222  circle->axis.x() * circle->p1.y();
223  return z1 + (std::sqrt(sqr(r) - sqr(tip)) - lip) * dzdu;
224  }
225 
226  Scalar radius2 = sqr(radius);
227 
228  Scalar b2 = center.mag2();
229  Scalar b = std::sqrt(b2);
230 
231  Scalar cos1 = 0.5 * curvature * (radius2 + b2 - sqr(r)) / b;
232  Scalar cos2 = 0.5 * curvature * (radius2 + b2 - circle->p1.mag2()) / b;
233 
234  Scalar phi1 = clamped_acos(cos1);
235  Scalar phi2 = clamped_acos(cos2);
236 
237  // more plausbility checks needed...
238  // the two circles can have two possible intersections
239  Scalar u1 = std::abs((phi1 - phi2) * radius);
240  Scalar u2 = std::abs((phi1 + phi2) * radius);
241 
242  return z1 + ((u1 >= seg && u1 < u2)? u1 : u2) * dzdu;
243 }
244 
247  if (unlikely(std::abs(dzdu) < 1.0e-5))
248  return 99999.0;
249 
250  if (unlikely(std::abs(curvature) < 1.0e-5)) {
251  Scalar tip = circle->axis * circle->p1;
252  Scalar lip = circle->axis.y() * circle->p1.x() -
253  circle->axis.x() * circle->p1.y();
254  return std::sqrt(sqr(tip) + sqr(lip + (z - z1) / dzdu));
255  }
256 
257  // we won't go below that (see comment below)
258  Scalar minR2 = (2. * circle->center - circle->p1).mag2();
259 
260  float phi = curvature * (z - z1) / dzdu;
261 
262  if (unlikely(std::abs(phi) > 2. * M_PI)) {
263  // with a helix we can get problems here - this is used to get the limits
264  // however, if phi gets large, we get into the regions where we loop back
265  // to smaller r's. The question is - do we care about these tracks?
266  // The answer is probably no: Too much pain, and the rest of the
267  // tracking won't handle looping tracks anyway.
268  // So, what we do here is to return nothing smaller than the radius
269  // than any of the two hits, i.e. the second hit, which is presumably
270  // outside of the 1st hit.
271 
272  return std::sqrt(minR2);
273  }
274 
275  Vector2D rel = circle->p1 - center;
276 
277  Scalar c = std::cos(phi);
278  Scalar s = std::sin(phi);
279 
280  Vector2D p(center.x() + c * rel.x() - s * rel.y(),
281  center.y() + s * rel.x() + c * rel.y());
282 
283  return std::sqrt(std::max(minR2, p.mag2()));
284 }
double transverseIP(const Vector2D &thirdPoint) const
Scalar invCenterOnAxis(const Vector2D &thirdPoint) const
float angle(float curvature, float radius) const
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
float sgn(float val)
Definition: FWPFMaths.cc:9
double sign(double x)
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
T y() const
Definition: PV3DBase.h:63
#define M_PI_2
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
T barePhi() const
#define constexpr
float float float z
Range curvature(double transverseIP) const
#define unlikely(x)
#define likely(x)
T curvature(T InversePt, const edm::EventSetup &iSetup)
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
T sqrt(T t)
Definition: SSEVec.h:48
T mag2() const
The vector magnitude squared. Equivalent to vec.dot(vec)
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
ThirdHitPredictionFromCircle::Scalar Scalar
double f[11][100]
static const double SMALL
Definition: herwig.h:292
double p2[4]
Definition: TauolaWrapper.h:90
T y() const
Cartesian y coordinate.
#define M_PI
ThirdHitPredictionFromCircle(const GlobalPoint &P1, const GlobalPoint &P2, float tolerance)
Range operator()(Range curvature, float radius) const
static double maxCurvature(const ThirdHitPredictionFromCircle *circle, double z1, double z2, double z3)
double b
Definition: hdecay.h:120
T mag2() const
The vector magnitude squared. Equivalent to vec.dot(vec)
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
double p1[4]
Definition: TauolaWrapper.h:89
double a
Definition: hdecay.h:121
Square< F >::type sqr(const F &f)
Definition: Square.h:13
const ThirdHitPredictionFromCircle * circle
Definition: DDAxes.h:10
Geom::Phi< T > phi() const
long double T
T x() const
Definition: PV3DBase.h:62
float phi(float curvature, float radius) const
T x() const
Cartesian x coordinate.