CMS 3D CMS Logo

TkRadialStripTopology.cc
Go to the documentation of this file.
3 
4 #include <iostream>
5 #include <cmath>
6 #include <algorithm>
7 #include <cassert>
8 
9 #include <vdt/vdtMath.h>
10 
11 #ifdef MATH_STS
12 #include <iostream>
13 #endif
14 namespace {
15 
16 #ifdef MATH_STS
17  struct Stat {
18  Stat(const char* in) : name(in){};
19  ~Stat() {
20  edm::LogVerbatim("CommonTopologies")
21  << name << ": atan0 calls tot/large/over1: " << natan << "/" << nlarge << "/" << over1;
22  }
23 
24  void add(float t) {
25  auto at = std::abs(t);
26  ++natan;
27  if (at > 0.40f)
28  ++nlarge;
29  if (at > 1.0)
30  ++over1;
31  }
32  const char* name;
33  long long natan = 0;
34  long long nlarge = 0;
35  long long over1 = 0;
36  };
37 
38  Stat statM("mpos");
39  Stat statS("span");
40 #endif
41 
42  // valid for |x| < 0.15 (better then 10^-9
43  template <typename T>
44  inline T tan15(T x) {
45  return x * (T(1) + (x * x) * (T(0.33331906795501708984375) + (x * x) * T(0.135160386562347412109375)));
46  }
47 
48  // valid for z < pi/8
49  // x * (1 + x*x * (-0.33322894573211669921875 + x*x * (0.1967026889324188232421875 + x*x * (-0.11053790152072906494140625)))) // .1e-7 by Sollya
50  inline float atan0(float t) {
51  auto z = t;
52  // if( t > 0.4142135623730950f ) // * tan pi/8
53  // z = (t-1.0f)/(t+1.0f);
54  float z2 = z * z;
55  float ret =
56  (((8.05374449538e-2f * z2 - 1.38776856032E-1f) * z2 + 1.99777106478E-1f) * z2 - 3.33329491539E-1f) * z2 * z + z;
57  // if( t > 0.4142135623730950f ) ret +=0.7853981633974483096f;
58  return ret;
59  }
60 
61  inline float atanClip(float t) {
62  constexpr float tanPi8 = 0.4142135623730950;
63  constexpr float pio8 = 3.141592653589793238 / 8;
64  float at = std::abs(t);
65  return std::copysign((at < tanPi8) ? atan0(at) : pio8, t);
66  }
67 
68 } // namespace
69 
70 TkRadialStripTopology::TkRadialStripTopology(int ns, float aw, float dh, float r, int yAx, float yMid)
71  : theNumberOfStrips(ns),
72  theAngularWidth(aw),
73  theAWidthInverse(1.f / aw),
74  theTanAW(std::tan(aw)),
75  theDetHeight(dh),
76  theCentreToIntersection(r),
77  theYAxisOrientation(yAx),
78  yCentre(yMid),
79  theRadialSigma(std::pow(dh, 2.f) * (1.f / 12.f)) {
80  // Angular offset of extreme edge of detector, so that angle is
81  // zero for a strip lying along local y axis = long symmetry axis of plane of strips
82  thePhiOfOneEdge = -(0.5 * theNumberOfStrips) * theAngularWidth; // always negative!
84  assert(std::abs(thePhiOfOneEdge) < 0.15); //
85 
86  LogTrace("TkRadialStripTopology") << "TkRadialStripTopology: constructed with"
87  << " strips = " << ns << " width = " << aw << " rad "
88  << " det_height = " << dh << " ctoi = " << r << " phi_edge = " << thePhiOfOneEdge
89  << " rad "
90  << " y_ax_ori = " << theYAxisOrientation << " y_det_centre = " << yCentre << "\n";
91 }
92 
94  return std::min(int(strip(lp)), theNumberOfStrips - 1);
95 }
96 
98  return std::min(nstrips(), static_cast<int>(std::max(float(0), strip(lp))) + 1);
99 }
100 
102  return yAxisOrientation() * y + originToIntersection();
103 }
104 
106  return detHeight() * std::sqrt(1.f + std::pow(lp.x() / yDistanceToIntersection(lp.y()), 2.f));
107 }
108 
109 float TkRadialStripTopology::xOfStrip(int strip, float y) const {
110  return yAxisOrientation() * yDistanceToIntersection(y) * std::tan(stripAngle(static_cast<float>(strip) - 0.5f));
111 }
112 
113 float TkRadialStripTopology::strip(const LocalPoint& lp) const {
114  // phi is measured from y axis --> sign of angle is sign of x * yAxisOrientation --> use atan2(x,y), not atan2(y,x)
115  const float phi = atanClip(lp.x() / yDistanceToIntersection(lp.y()));
116  const float aStrip = (phi - phiOfOneEdge()) * theAWidthInverse;
117  return std::max(float(0), std::min((float)nstrips(), aStrip));
118 }
119 
120 float TkRadialStripTopology::coveredStrips(const LocalPoint& lp1, const LocalPoint& lp2) const {
121  // http://en.wikipedia.org/wiki/List_of_trigonometric_identities#Angle_sum_and_difference_identities
122  // atan(a)-atan(b) = atan( (a-b)/(1+a*b) )
123  // avoid divisions
124  // float t1 = lp1.x()/yDistanceToIntersection( lp1.y() );
125  // float t2 = lp2.x()/yDistanceToIntersection( lp2.y() );
126  // float t = (t1-t2)/(1.+t1*t2);
127  auto y1 = yDistanceToIntersection(lp1.y());
128  auto y2 = yDistanceToIntersection(lp2.y());
129  auto x1 = lp1.x();
130  auto x2 = lp2.x();
131 
132  auto t = (y2 * x1 - y1 * x2) / (y1 * y2 + x1 * x2);
133 
134 #ifdef MATH_STS
135  statS.add(t);
136 #endif
137  // edm::LogVerbatim("CommonTopologies") << "atans " << atanClip(t) << " " << std::atan2(lp1.x(), yDistanceToIntersection(lp1.y())) - std::atan2(lp2.x(),yDistanceToIntersection(lp2.y()));
138  // clip???
139  return atanClip(t) * theAWidthInverse;
140  // return (measurementPosition(lp1)-measurementPosition(lp2)).x();
141 }
142 
145 }
146 
148  const float // y = (L/cos(phi))*mp.y()*cos(phi)
149  y(mp.y() * detHeight() + yCentreOfStripPlane()),
151  return LocalPoint(x, y);
152 }
153 
155  // phi is [pi/2 - conventional local phi], use atan2(x,y) rather than atan2(y,x)
156  // clip ( at pi/8 or detedge+tollerance?)
157  float t = lp.x() / yDistanceToIntersection(lp.y());
158 #ifdef MATH_STS
159  statM.add(t);
160 #endif
161  const float phi = atanClip(t);
163 }
164 
165 LocalError TkRadialStripTopology::localError(float strip, float stripErr2) const {
166  double phi = stripAngle(strip);
167 
168  const double t1(tan15(phi)), // std::tan(phif)), // (vdt::fast_tanf(phif)),
169  t2(t1 * t1),
170  // s1(std::sin(phi)), c1(std::cos(phi)),
171  // cs(s1*c1), s2(s1*s1), c2(1-s2), // rotation matrix
172 
173  tt(stripErr2 * std::pow(centreToIntersection() * angularWidth(), 2.f)), // tangential sigma^2 *c2
174  rr(theRadialSigma), // radial sigma^2( uniform prob density along strip) *c2
175 
176  xx(tt + t2 * rr), yy(t2 * tt + rr), xy(t1 * (rr - tt));
177 
178  return LocalError(xx, xy, yy);
179 }
180 
182  const double phi(stripAngle(mp.x())), s1(std::sin(phi)), c1(std::cos(phi)), cs(s1 * c1), s2(s1 * s1),
183  c2(1 - s2), // rotation matrix
184 
186  c1), // tangential measurement unit (local pitch)
187  R(detHeight() / c1), // radial measurement unit (strip length)
188  tt(me.uu() * T * T), // tangential sigma^2
189  rr(me.vv() * R * R), // radial sigma^2
190  tr(me.uv() * T * R),
191 
192  xx(c2 * tt + 2 * cs * tr + s2 * rr), yy(s2 * tt - 2 * cs * tr + c2 * rr), xy(cs * (rr - tt) + tr * (c2 - s2));
193 
194  return LocalError(xx, xy, yy);
195 }
196 
198  const double yHitToInter(yDistanceToIntersection(p.y())),
199  t(yAxisOrientation() * p.x() / yHitToInter), // tan(strip angle)
200  cs(t / (1 + t * t)), s2(t * cs), c2(1 - s2), // rotation matrix
201 
202  T2(1. / (std::pow(angularWidth(), 2.f) *
203  (std::pow(p.x(), 2.f) + std::pow(yHitToInter, 2)))), // 1./tangential measurement unit (local pitch) ^2
204  R2(c2 / std::pow(detHeight(), 2.f)), // 1./ radial measurement unit (strip length) ^2
205 
206  uu((c2 * e.xx() - 2 * cs * e.xy() + s2 * e.yy()) * T2), vv((s2 * e.xx() + 2 * cs * e.xy() + c2 * e.yy()) * R2),
207  uv((cs * (e.xx() - e.yy()) + e.xy() * (c2 - s2)) * std::sqrt(T2 * R2));
208 
209  return MeasurementError(uu, uv, vv);
210 }
211 
212 // The local pitch is the local x width of the strip at the local (x,y)
214  // this should be ~ y*(tan(phi+aw)-tan(phi)) = -x + y*(tan(aw)+tan(phi))/(1.f-tan(aw)*tan(phi)) tan(phi)=x/y
215  float y = yDistanceToIntersection(lp.y());
216  float x = std::abs(lp.x());
217  return y * (y * theTanAW + x) / (y - theTanAW * x) - x;
218 }
219 
220 /* old version
221 float TkRadialStripTopology::localPitch(const LocalPoint& lp) const {
222  // this should be ~ y*(tan(phi+aw)-tan(phi)) = -tan(phi) + (tan(aw)+tan(phi))/(1.f-tan(aw)*tan(phi))
223  const int istrip = std::min(nstrips(), static_cast<int>(strip(lp)) + 1); // which strip number
224  float fangle = stripAngle(static_cast<float>(istrip) - 0.5); // angle of strip centre
225  float p =
226  yDistanceToIntersection( lp.y() ) * std::sin(angularWidth()) /
227  std::pow( std::cos(fangle-0.5f*angularWidth()), 2.f);
228 
229  float theTanAW = std::tan(theAngularWidth);
230  float y = yDistanceToIntersection( lp.y() );
231  float x = std::abs(lp.x());
232  float myP = y*(y*theTanAW+x)/(y-theTanAW*x)-x; // (y*theTanAW+x)/(1.f-theTanAW*x/y)-x;
233  edm::LogVerbatim("CommonTopologies") << "localPitch " << p << " " << myP;
234 
235  return p;
236 
237 }
238 */
Log< level::Info, true > LogVerbatim
int channel(const LocalPoint &) const override
Point3DBase< Scalar, LocalTag > LocalPoint
Definition: Definitions.h:30
float stripAngle(float strip) const override
ret
prodAgent to be discontinued
float xOfStrip(int strip, float y) const override
TkRadialStripTopology(int ns, float aw, float dh, float r, int yAx=1, float yMid=0.)
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
constexpr int pow(int x)
Definition: conifer.h:24
T x() const
Definition: PV2DBase.h:43
int nstrips() const override
float originToIntersection() const override
assert(be >=bs)
float float float z
#define LogTrace(id)
T y() const
Definition: PV2DBase.h:44
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
Measurement2DPoint MeasurementPoint
Measurement points are two-dimensional by default.
Definition: TTTypes.h:54
float strip(const LocalPoint &) const override
int nearestStrip(const LocalPoint &) const override
T sqrt(T t)
Definition: SSEVec.h:19
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
LocalError localError(float strip, float stripErr2) const override
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
float localStripLength(const LocalPoint &) const override
float localPitch(const LocalPoint &) const override
double f[11][100]
float angularWidth() const override
float centreToIntersection() const override
float coveredStrips(const LocalPoint &lp1, const LocalPoint &lp2) const override
float yCentreOfStripPlane() const override
MeasurementPoint measurementPosition(const LocalPoint &) const override
MeasurementError measurementError(const LocalPoint &, const LocalError &) const override
void add(std::map< std::string, TH1 *> &h, TH1 *hist)
float detHeight() const override
float yDistanceToIntersection(float y) const override
float x
float yAxisOrientation() const override
dh
Definition: cuy.py:354
long double T
float phiOfOneEdge() const override
LocalPoint localPosition(float strip) const override