CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ThirdHitPredictionFromInvParabola.cc
Go to the documentation of this file.
1 
3 
4 #include <cmath>
7 
11 
13 
14 namespace {
15  template <class T> inline T sqr( T t) {return t*t;}
16 }
17 
18 using namespace std;
19 
21  const GlobalPoint& P1, const GlobalPoint& P2,Scalar ip, Scalar curv, Scalar tolerance)
22  : theTolerance(tolerance)
23 {
24  init(P1,P2,ip,std::abs(curv));
25 }
26 
27 
29 // GlobalVector aX = GlobalVector( P2.x()-P1.x(), P2.y()-P1.y(), 0.).unit();
30 
31  Point2D p1(x1,y1);
32  Point2D p2(x2,y2);
33  theRotation = Rotation(p1);
34  p1 = transform(p1); // (1./P1.xy().mag(),0);
35  p2 = transform(p2);
36 
37 
38  u1u2 = p1.x()*p2.x();
39  overDu = 1./(p2.x() - p1.x());
40  pv = p1.y()*p2.x() - p2.y()*p1.x();
41  dv = p2.y() - p1.y();
42  su = p2.x() + p1.x();
43 
44  ip = std::abs(ip);
45  RangeD ipRange(-ip, ip);
46 
47 
48  Scalar ipIntyPlus = ipFromCurvature(0.,true);
49  Scalar ipCurvPlus = ipFromCurvature(curv, true);
50  Scalar ipCurvMinus = ipFromCurvature(curv, false);
51 
52 
53  RangeD ipRangePlus(std::min(ipIntyPlus, ipCurvPlus),std::max(ipIntyPlus, ipCurvPlus));
54  RangeD ipRangeMinus(std::min(-ipIntyPlus, ipCurvMinus),std::max(-ipIntyPlus, ipCurvMinus));
55 
56  theIpRangePlus = ipRangePlus.intersection(ipRange);
57  theIpRangeMinus = ipRangeMinus.intersection(ipRange);
58 
61 
62 }
63 
64 
65 
68 {
69  bool pos = icharge>0;
70 
71  RangeD ip = (pos) ? theIpRangePlus : theIpRangeMinus;
72 
73 
74  // it will vectorize with gcc 4.7 (with -O3 -fno-math-errno)
75  // change sign as intersect assume -ip for negative charge...
76  Scalar ipv[2]={(pos)? ip.min() : -ip.min() ,(pos)? ip.max() : -ip.max()};
77  Scalar u[2], v[2];
78  for (int i=0; i!=2; ++i)
79  findPointAtCurve(radius,ipv[i],u[i],v[i]);
80 
81  //
82  Scalar phi1 = theRotation.rotateBack(Point2D(u[0],v[0])).barePhi();
83  Scalar phi2 = phi1+(v[1]-v[0]);
84 
85  if (ip.empty()) {
86  Range r1(phi1*radius-theTolerance, phi1*radius+theTolerance);
87  Range r2(phi2*radius-theTolerance, phi2*radius+theTolerance);
88  return r1.intersection(r2);
89  }
90 
91  if (phi2<phi1) std::swap(phi1, phi2);
92  return Range(radius*phi1-theTolerance, radius*phi2+theTolerance);
93 
94 
95 }
96 
97 
98 namespace {
99 
100  // original from chephes single precision version
101  template<typename T>
102  inline T atan2_fast( T y, T x ) {
103 
104  constexpr T PIO4F = 0.7853981633974483096;
105  constexpr T PIF = 3.141592653589793238;
106  constexpr T PIO2F = 1.5707963267948966192;
107 
108  // move in first octant
109  T xx = std::abs(x);
110  T yy = std::abs(y);
111  T tmp = T(0);
112  if (yy>xx) {
113  tmp = yy;
114  yy=xx; xx=tmp;
115  }
116  T t=yy/xx;
117  T z =
118  ( t > T(0.4142135623730950) ) ? // * tan pi/8
119  (t-T(1.0))/(t+T(1.0)) : t;
120 
121 
122  //printf("%e %e %e %e\n",yy,xx,t,z);
123  T z2 = z * z;
124  T ret = // (y==0) ? 0 : // no protection for (0,0)
125  ((( T(8.05374449538e-2) * z2
126  - T(1.38776856032E-1)) * z2
127  + T(1.99777106478E-1)) * z2
128  - T(3.33329491539E-1)) * z2 * z
129  + z;
130 
131  // move back in place
132  if( t > T(0.4142135623730950) ) ret += PIO4F;
133  if (tmp!=0) ret = PIO2F - ret;
134  if (x<0) ret = PIF - ret;
135  if (y<0) ret = -ret;
136 
137  return ret;
138 
139  }
140 
141 
142 
143 
144 }
145 
146 
149 {
150 
151  auto getRange = [&](Scalar phi1, Scalar phi2, bool empty)->RangeD {
152 
153  if (empty) {
154  RangeD r1(phi1*radius-theTolerance, phi1*radius+theTolerance);
155  RangeD r2(phi2*radius-theTolerance, phi2*radius+theTolerance);
156  return r1.intersection(r2);
157  }
158 
159  return RangeD(radius*std::min(phi1,phi2)-theTolerance, radius*std::max(phi1,phi2)+theTolerance);
160  };
161 
162 
163  // it will vectorize with gcc 4.7 (with -O3 -fno-math-errno)
164  // change sign as intersect assume -ip for negative charge...
166  Scalar u[4], v[4];
167  for (int i=0; i<4; ++i)
168  findPointAtCurve(radius,ipv[i],u[i],v[i]);
169 
170  //
171  auto xr = theRotation.x();
172  auto yr = theRotation.y();
173 
174  Scalar phi1[2],phi2[2];
175  for (int i=0; i<2; ++i) {
176  auto x = xr[0]*u[i] + yr[0]*v[i];
177  auto y = xr[1]*u[i] + yr[1]*v[i];
178  phi1[i] = atan2_fast(y,x);
179  phi2[i] = phi1[i]+(v[i+2]-v[i]);
180  }
181 
182 
183  return getRange(phi1[1],phi2[1],emptyM).sum(getRange(phi1[0],phi2[0],emptyP));
184 
185  /*
186  Scalar phi1P = theRotation.rotateBack(Point2D(u[0],v[0])).barePhi();
187  Scalar phi2P= phi1P+(v[2]-v[0]);
188 
189  Scalar phi1M = theRotation.rotateBack(Point2D(u[1],v[1])).barePhi();
190  Scalar phi2M = phi1M+(v[3]-v[1]);
191 
192 
193  return getRange(phi1M,phi2M,emptyM).sum(getRange(phi1P,phi2P,emptyP));
194 
195  */
196 
197 }
198 
199 
200 /*
201 ThirdHitPredictionFromInvParabola::Range ThirdHitPredictionFromInvParabola::rangeRPhiSlow(
202  Scalar radius, int charge, int nIter) const
203 {
204  Range predRPhi(1.,-1.);
205 
206  Scalar invr2 = 1/(radius*radius);
207  Scalar u = sqrt(invr2);
208  Scalar v = 0.;
209 
210  Range ip = (charge > 0) ? theIpRangePlus : theIpRangeMinus;
211 
212  for (int i=0; i < nIter; ++i) {
213  v = predV(u, charge*ip.min());
214  Scalar d2 = invr2-sqr(v);
215  u = (d2 > 0) ? sqrt(d2) : 0.;
216  }
217  Point2D pred_tmp1(u, v);
218  Scalar phi1 = transformBack(pred_tmp1).phi();
219  while ( phi1 >= M_PI) phi1 -= 2*M_PI;
220  while ( phi1 < -M_PI) phi1 += 2*M_PI;
221 
222 
223  u = sqrt(invr2);
224  v=0;
225  for (int i=0; i < nIter; ++i) {
226  v = predV(u, ip.max(), charge);
227  Scalar d2 = invr2-sqr(v);
228  u = (d2 > 0) ? sqrt(d2) : 0.;
229  }
230  Point2D pred_tmp2(u, v);
231  Scalar phi2 = transformBack(pred_tmp2).phi();
232  while ( phi2-phi1 >= M_PI) phi2 -= 2*M_PI;
233  while ( phi2-phi1 < -M_PI) phi2 += 2*M_PI;
234 
235 // check faster alternative, without while(..) it is enough to:
236 // phi2 = phi1+radius*(pred_tmp2.v()-pred_tmp1.v());
237 
238  if (ip.empty()) {
239  Range r1(phi1*radius-theTolerance, phi1*radius+theTolerance);
240  Range r2(phi2*radius-theTolerance, phi2*radius+theTolerance);
241  predRPhi = r1.intersection(r2);
242  } else {
243  Range r(phi1, phi2);
244  r.sort();
245  predRPhi= Range(radius*r.min()-theTolerance, radius*r.max()+theTolerance);
246  }
247  return predRPhi;
248 
249 }
250 */
251 
int i
Definition: DBlmapReader.cc:9
T max() const
BasicVector x() const
bool empty() const
T barePhi() const
T min() const
BasicVector y() const
#define constexpr
float float float z
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
std::pair< typename T::DetSet::const_iterator, typename T::DetSet::const_iterator > getRange(const T &detset, const DetId &id)
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
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
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
Definition: DDAxes.h:10
long double T
T x() const
Cartesian x coordinate.