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 
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 (ip.empty()) {
93  Range r1(phi1*radius-theTolerance, phi1*radius+theTolerance);
94  Range r2(phi2*radius-theTolerance, phi2*radius+theTolerance);
95  return r1.intersection(r2);
96  }
97 
98  if (phi2<phi1) std::swap(phi1, phi2);
99  return Range(radius*phi1-theTolerance, radius*phi2+theTolerance);
100 
101 
102 }
103 
104 
107 {
108 
109  auto getRange = [&](Scalar phi1, Scalar phi2, bool empty)->RangeD {
110 
111  if (empty) {
112  RangeD r1(phi1*radius-theTolerance, phi1*radius+theTolerance);
113  RangeD r2(phi2*radius-theTolerance, phi2*radius+theTolerance);
114  return r1.intersection(r2);
115  }
116 
117  return RangeD(radius*std::min(phi1,phi2)-theTolerance, radius*std::max(phi1,phi2)+theTolerance);
118  };
119 
120 
121  // it will vectorize with gcc 4.7 (with -O3 -fno-math-errno)
122  // change sign as intersect assume -ip for negative charge...
124  Scalar u[4], v[4];
125  for (int i=0; i<4; ++i)
126  findPointAtCurve(radius,ipv[i],u[i],v[i]);
127 
128  //
129  auto xr = theRotation.x();
130  auto yr = theRotation.y();
131 
132  Scalar phi1[2],phi2[2];
133  for (int i=0; i<2; ++i) {
134  auto x = xr[0]*u[i] + yr[0]*v[i];
135  auto y = xr[1]*u[i] + yr[1]*v[i];
136  phi1[i] = f_atan2f(y,x);
137  phi2[i] = phi1[i]+(v[i+2]-v[i]);
138  }
139 
140  return getRange(phi1[1],phi2[1],emptyM).sum(getRange(phi1[0],phi2[0],emptyP));
141 }
142 
143 
144 /*
145 ThirdHitPredictionFromInvParabola::Range ThirdHitPredictionFromInvParabola::rangeRPhiSlow(
146  Scalar radius, int charge, int nIter) const
147 {
148  Range predRPhi(1.,-1.);
149 
150  Scalar invr2 = 1/(radius*radius);
151  Scalar u = sqrt(invr2);
152  Scalar v = 0.;
153 
154  Range ip = (charge > 0) ? theIpRangePlus : theIpRangeMinus;
155 
156  for (int i=0; i < nIter; ++i) {
157  v = predV(u, charge*ip.min());
158  Scalar d2 = invr2-sqr(v);
159  u = (d2 > 0) ? sqrt(d2) : 0.;
160  }
161  Point2D pred_tmp1(u, v);
162  Scalar phi1 = transformBack(pred_tmp1).phi();
163  while ( phi1 >= M_PI) phi1 -= 2*M_PI;
164  while ( phi1 < -M_PI) phi1 += 2*M_PI;
165 
166 
167  u = sqrt(invr2);
168  v=0;
169  for (int i=0; i < nIter; ++i) {
170  v = predV(u, ip.max(), charge);
171  Scalar d2 = invr2-sqr(v);
172  u = (d2 > 0) ? sqrt(d2) : 0.;
173  }
174  Point2D pred_tmp2(u, v);
175  Scalar phi2 = transformBack(pred_tmp2).phi();
176  while ( phi2-phi1 >= M_PI) phi2 -= 2*M_PI;
177  while ( phi2-phi1 < -M_PI) phi2 += 2*M_PI;
178 
179 // check faster alternative, without while(..) it is enough to:
180 // phi2 = phi1+radius*(pred_tmp2.v()-pred_tmp1.v());
181 
182  if (ip.empty()) {
183  Range r1(phi1*radius-theTolerance, phi1*radius+theTolerance);
184  Range r2(phi2*radius-theTolerance, phi2*radius+theTolerance);
185  predRPhi = r1.intersection(r2);
186  } else {
187  Range r(phi1, phi2);
188  r.sort();
189  predRPhi= Range(radius*r.min()-theTolerance, radius*r.max()+theTolerance);
190  }
191  return predRPhi;
192 
193 }
194 */
195 
int i
Definition: DBlmapReader.cc:9
T max() const
BasicVector x() const
bool empty() const
T min() const
BasicVector y() const
void init(const GlobalPoint &P1, const GlobalPoint &P2, Scalar ip, Scalar curv)
T x() const
Cartesian x coordinate.
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.