1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
/**GEMStripTopology
* based on CSCRadialStripTopology and TrapezoidalStripTopology
* \author Hyunyong Kim - TAMU
*/
#include "Geometry/CommonTopologies/interface/GEMStripTopology.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include <iostream>
#include <cmath>
#include <algorithm>
GEMStripTopology::GEMStripTopology(int ns, float aw, float dh, float r0)
: numberOfStrips_(ns), angularWidth_(aw), detHeight_(dh), centreToIntersection_(r0) {
assert(angularWidth_ != 0);
assert(detHeight_ != 0);
yAxisOrientation_ = 1;
phiOfOneEdge_ = -(0.5 * numberOfStrips_) * angularWidth_ * yAxisOrientation_;
yCentre_ = 0;
LogTrace("GEMStripTopology") << "Constructing GEMStripTopology with"
<< " nstrips = " << ns << " angular width = " << aw << " det. height = " << dh
<< " r0 = " << r0 << "\n";
}
GEMStripTopology::GEMStripTopology(int ns, float aw, float dh, float r0, float yAx)
: numberOfStrips_(ns), angularWidth_(aw), detHeight_(dh), centreToIntersection_(r0), yAxisOrientation_(yAx) {
assert(angularWidth_ != 0);
assert(detHeight_ != 0);
phiOfOneEdge_ = -(0.5 * numberOfStrips_) * angularWidth_ * yAxisOrientation_;
yCentre_ = 0;
LogTrace("GEMStripTopology") << "Constructing GEMStripTopology with"
<< " nstrips = " << ns << " angular width = " << aw << " det. height = " << dh
<< " r0 = " << r0 << " yAxOrientation = " << yAx << "\n";
}
LocalPoint GEMStripTopology::localPosition(float strip) const {
return LocalPoint(yAxisOrientation() * originToIntersection() * tan(stripAngle(strip)), 0);
}
LocalPoint GEMStripTopology::localPosition(const MeasurementPoint& mp) const {
const float // y = (L/cos(phi))*mp.y()*cos(phi)
y(mp.y() * detHeight() + yCentreOfStripPlane()),
x(yAxisOrientation() * yDistanceToIntersection(y) * std::tan(stripAngle(mp.x())));
return LocalPoint(x, y);
}
LocalError GEMStripTopology::localError(float strip, float stripErr2) const {
const double phi(stripAngle(strip)), t1(std::tan(phi)), t2(t1 * t1),
tt(stripErr2 * std::pow(centreToIntersection() * angularWidth(), 2)), // tangential sigma^2 *c2
rr(std::pow(detHeight(), 2) * (1.f / 12.f)), // radial sigma^2( uniform prob density along strip) *c2
xx(tt + t2 * rr), yy(t2 * tt + rr), xy(t1 * (rr - tt));
return LocalError(xx, xy, yy);
}
LocalError GEMStripTopology::localError(const MeasurementPoint& mp, const MeasurementError& me) const {
const double phi(stripAngle(mp.x())), s1(std::sin(phi)), c1(std::cos(phi));
assert(c1 != 0);
const double cs(s1 * c1), s2(s1 * s1),
c2(1 - s2), // rotation matrix
T(angularWidth() * (centreToIntersection() + yAxisOrientation() * mp.y() * detHeight()) /
c1), // tangential measurement unit (local pitch)
R(detHeight() / c1), // radial measurement unit (strip length)
tt(me.uu() * T * T), // tangential sigma^2
rr(me.vv() * R * R), // radial sigma^2
tr(me.uv() * T * R),
xx(c2 * tt + 2 * cs * tr + s2 * rr), yy(s2 * tt - 2 * cs * tr + c2 * rr), xy(cs * (rr - tt) + tr * (c2 - s2));
return LocalError(xx, xy, yy);
}
float GEMStripTopology::strip(const LocalPoint& lp) const {
const float // phi is measured from y axis --> sign of angle is sign of x * yAxisOrientation --> use atan2(x,y), not atan2(y,x)
phi(std::atan2(lp.x(), yDistanceToIntersection(lp.y()))),
aStrip((phi - yAxisOrientation() * phiOfOneEdge()) / angularWidth());
return std::max(float(0), std::min((float)nstrips(), aStrip));
}
int GEMStripTopology::nearestStrip(const LocalPoint& lp) const {
return std::min(nstrips(), static_cast<int>(std::max(float(0), strip(lp))) + 1);
}
MeasurementPoint GEMStripTopology::measurementPosition(const LocalPoint& lp) const {
const float // phi is [pi/2 - conventional local phi], use atan2(x,y) rather than atan2(y,x)
phi(yAxisOrientation() * std::atan2(lp.x(), yDistanceToIntersection(lp.y())));
return MeasurementPoint(yAxisOrientation() * (phi - phiOfOneEdge()) / angularWidth(),
(lp.y() - yCentreOfStripPlane()) / detHeight());
}
MeasurementError GEMStripTopology::measurementError(const LocalPoint& p, const LocalError& e) const {
const double yHitToInter(yDistanceToIntersection(p.y()));
assert(yHitToInter != 0);
const double t(yAxisOrientation() * p.x() / yHitToInter), // tan(strip angle)
cs(t / (1 + t * t)), s2(t * cs), c2(1 - s2), // rotation matrix
T2(1. / (std::pow(angularWidth(), 2) *
(std::pow(p.x(), 2) + std::pow(yHitToInter, 2)))), // 1./tangential measurement unit (local pitch) ^2
R2(c2 / std::pow(detHeight(), 2)), // 1./ radial measurement unit (strip length) ^2
uu((c2 * e.xx() - 2 * cs * e.xy() + s2 * e.yy()) * T2), vv((s2 * e.xx() + 2 * cs * e.xy() + c2 * e.yy()) * R2),
uv((cs * (e.xx() - e.yy()) + e.xy() * (c2 - s2)) * std::sqrt(T2 * R2));
return MeasurementError(uu, uv, vv);
}
int GEMStripTopology::channel(const LocalPoint& lp) const { return std::min(int(strip(lp)), numberOfStrips_ - 1); }
float GEMStripTopology::pitch() const { return localPitch(LocalPoint(0, 0)); }
float GEMStripTopology::localPitch(const LocalPoint& lp) const {
const int istrip = std::min(nstrips(), static_cast<int>(strip(lp)) + 1); // which strip number
const float fangle = stripAngle(static_cast<float>(istrip) - 0.5); // angle of strip centre
assert(std::cos(fangle - 0.5f * angularWidth()) != 0);
return yDistanceToIntersection(lp.y()) * std::sin(angularWidth()) /
std::pow(std::cos(fangle - 0.5f * angularWidth()), 2);
}
float GEMStripTopology::stripAngle(float strip) const {
return phiOfOneEdge() + yAxisOrientation() * strip * angularWidth();
}
float GEMStripTopology::localStripLength(const LocalPoint& lp) const {
assert(yDistanceToIntersection(lp.y()) != 0);
return detHeight() * std::sqrt(1.f + std::pow(lp.x() / yDistanceToIntersection(lp.y()), 2));
}
float GEMStripTopology::yDistanceToIntersection(float y) const {
return yAxisOrientation() * y + originToIntersection();
}
float GEMStripTopology::xOfStrip(int strip, float y) const {
return yAxisOrientation() * yDistanceToIntersection(y) * std::tan(stripAngle(static_cast<float>(strip) - 0.5));
}
|