CMS 3D CMS Logo

ThirdHitPredictionFromInvParabola.cc
Go to the documentation of this file.
1 
3 
4 #include <cmath>
7 
11 
13 
15 namespace {
16  inline float f_atan2f(float y, float x) { return unsafe_atan2f<7>(y, x); }
17  template <typename V>
18  inline float f_phi(V v) {
19  return f_atan2f(v.y(), v.x());
20  }
21 } // namespace
22 
23 namespace {
24  template <class T>
25  inline T sqr(T t) {
26  return t * t;
27  }
28 } // namespace
29 
30 using namespace std;
31 
33  const GlobalPoint& P1, const GlobalPoint& P2, Scalar ip, Scalar curv, Scalar tolerance)
34  : theTolerance(tolerance) {
35  init(P1, P2, ip, std::abs(curv));
36 }
37 
39  // GlobalVector aX = GlobalVector( P2.x()-P1.x(), P2.y()-P1.y(), 0.).unit();
40 
41  Point2D p1(x1, y1);
42  Point2D p2(x2, y2);
43  theRotation = Rotation(p1);
44  p1 = transform(p1); // (1./P1.xy().mag(),0);
45  p2 = transform(p2);
46 
47  u1u2 = p1.x() * p2.x();
48  overDu = 1. / (p2.x() - p1.x());
49  pv = p1.y() * p2.x() - p2.y() * p1.x();
50  dv = p2.y() - p1.y();
51  su = p2.x() + p1.x();
52 
53  ip = std::abs(ip);
54  RangeD ipRange(-ip, ip);
55 
56  Scalar ipIntyPlus = ipFromCurvature(0., true);
57  Scalar ipCurvPlus = ipFromCurvature(curv, true);
58  Scalar ipCurvMinus = ipFromCurvature(curv, false);
59 
60  RangeD ipRangePlus(std::min(ipIntyPlus, ipCurvPlus), std::max(ipIntyPlus, ipCurvPlus));
61  RangeD ipRangeMinus(std::min(-ipIntyPlus, ipCurvMinus), std::max(-ipIntyPlus, ipCurvMinus));
62 
63  theIpRangePlus = ipRangePlus.intersection(ipRange);
64  theIpRangeMinus = ipRangeMinus.intersection(ipRange);
65 
68 }
69 
71  int icharge) const {
72  bool pos = icharge > 0;
73 
74  RangeD ip = (pos) ? theIpRangePlus : theIpRangeMinus;
75 
76  // it will vectorize with gcc 4.7 (with -O3 -fno-math-errno)
77  // change sign as intersect assume -ip for negative charge...
78  Scalar ipv[2] = {(pos) ? ip.min() : -ip.min(), (pos) ? ip.max() : -ip.max()};
79  Scalar u[2], v[2];
80  for (int i = 0; i != 2; ++i)
81  findPointAtCurve(radius, ipv[i], u[i], v[i]);
82 
83  //
84  Scalar phi1 = f_phi(theRotation.rotateBack(Point2D(u[0], v[0])));
85  Scalar phi2 = phi1 + (v[1] - v[0]);
86 
87  if (phi2 < phi1)
88  std::swap(phi1, phi2);
89 
90  if (ip.empty()) {
91  Range r1(phi1 * radius - theTolerance, phi1 * radius + theTolerance);
92  Range r2(phi2 * radius - theTolerance, phi2 * radius + theTolerance);
93  return r1.intersection(r2); // this range can be empty
94  }
95 
96  return Range(radius * phi1 - theTolerance, radius * phi2 + theTolerance);
97 }
98 
100  auto getRange = [&](Scalar phi1, Scalar phi2, bool empty) -> RangeD {
101  if (phi2 < phi1)
102  std::swap(phi1, phi2);
103  if (empty) {
104  RangeD r1(phi1 * radius - theTolerance, phi1 * radius + theTolerance);
105  RangeD r2(phi2 * radius - theTolerance, phi2 * radius + theTolerance);
106  return r1.intersection(r2);
107  }
108 
109  return RangeD(radius * phi1 - theTolerance, radius * phi2 + theTolerance);
110  };
111 
112  // it will vectorize with gcc 4.7 (with -O3 -fno-math-errno)
113  // change sign as intersect assume -ip for negative charge...
115  Scalar u[4], v[4];
116  for (int i = 0; i < 4; ++i)
117  findPointAtCurve(radius, ipv[i], u[i], v[i]);
118 
119  //
120  auto xr = theRotation.x();
121  auto yr = theRotation.y();
122 
123  Scalar phi1[2], phi2[2];
124  for (int i = 0; i < 2; ++i) {
125  auto x = xr[0] * u[i] + yr[0] * v[i];
126  auto y = xr[1] * u[i] + yr[1] * v[i];
127  phi1[i] = f_atan2f(y, x);
128  phi2[i] = phi1[i] + (v[i + 2] - v[i]);
129  }
130 
131  return getRange(phi1[1], phi2[1], emptyM).sum(getRange(phi1[0], phi2[0], emptyP));
132 }
133 
134 /*
135 ThirdHitPredictionFromInvParabola::Range ThirdHitPredictionFromInvParabola::rangeRPhiSlow(
136  Scalar radius, int charge, int nIter) const
137 {
138  Range predRPhi(1.,-1.);
139 
140  Scalar invr2 = 1/(radius*radius);
141  Scalar u = sqrt(invr2);
142  Scalar v = 0.;
143 
144  Range ip = (charge > 0) ? theIpRangePlus : theIpRangeMinus;
145 
146  for (int i=0; i < nIter; ++i) {
147  v = predV(u, charge*ip.min());
148  Scalar d2 = invr2-sqr(v);
149  u = (d2 > 0) ? sqrt(d2) : 0.;
150  }
151  Point2D pred_tmp1(u, v);
152  Scalar phi1 = transformBack(pred_tmp1).phi();
153  while ( phi1 >= M_PI) phi1 -= 2*M_PI;
154  while ( phi1 < -M_PI) phi1 += 2*M_PI;
155 
156 
157  u = sqrt(invr2);
158  v=0;
159  for (int i=0; i < nIter; ++i) {
160  v = predV(u, ip.max(), charge);
161  Scalar d2 = invr2-sqr(v);
162  u = (d2 > 0) ? sqrt(d2) : 0.;
163  }
164  Point2D pred_tmp2(u, v);
165  Scalar phi2 = transformBack(pred_tmp2).phi();
166  while ( phi2-phi1 >= M_PI) phi2 -= 2*M_PI;
167  while ( phi2-phi1 < -M_PI) phi2 += 2*M_PI;
168 
169 // check faster alternative, without while(..) it is enough to:
170 // phi2 = phi1+radius*(pred_tmp2.v()-pred_tmp1.v());
171 
172  if (ip.empty()) {
173  Range r1(phi1*radius-theTolerance, phi1*radius+theTolerance);
174  Range r2(phi2*radius-theTolerance, phi2*radius+theTolerance);
175  predRPhi = r1.intersection(r2);
176  } else {
177  Range r(phi1, phi2);
178  r.sort();
179  predRPhi= Range(radius*r.min()-theTolerance, radius*r.max()+theTolerance);
180  }
181  return predRPhi;
182 
183 }
184 */
T max() const
const double tolerance
BasicVector x() const
bool empty() const
T min() const
BasicVector y() const
void init(const GlobalPoint &P1, const GlobalPoint &P2, Scalar ip, Scalar curv)
Range rangeRPhi(Scalar radius, int charge) const
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
T min(T a, T b)
Definition: MathUtil.h:58
double p2[4]
Definition: TauolaWrapper.h:90
T y() const
Cartesian y coordinate.
Scalar ipFromCurvature(Scalar curvature, bool pos) const
void findPointAtCurve(Scalar radius, Scalar ip, Scalar &u, Scalar &v) const
double p1[4]
Definition: TauolaWrapper.h:89
PixelRecoRange< T > intersection(const PixelRecoRange< T > &r) const
Square< F >::type sqr(const F &f)
Definition: Square.h:14
BasicVector rotateBack(const BasicVector &v) const
long double T
T x() const
Cartesian x coordinate.