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