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
|
#include "Geometry/MTDGeometryBuilder/interface/RectangularMTDTopology.h"
//--------------------------------------------------------------------
// PixelTopology interface.
// Transform LocalPoint in cm to measurement in pitch units.
std::pair<float, float> RectangularMTDTopology::pixel(const LocalPoint& p) const {
// check limits
float py = p.y();
float px = p.x();
// In Y
float newybin = (py - m_yoffset) / m_pitchy;
// In X
float newxbin = (px - m_xoffset) / m_pitchx;
return std::pair<float, float>(newxbin, newybin);
}
//provide pixel indices based on local module position (with protection for border positions)
std::pair<int, int> RectangularMTDTopology::pixelIndex(const LocalPoint& p) const {
const auto& thepixel = pixel(p);
bool fail(false);
static constexpr float tol = 5e-5f; // 0.5 micron tolerance
int row = static_cast<int>(thepixel.first);
if (row >= m_nrows) {
fail = (p.x() - m_pitchx * m_nrows > tol);
if (!fail) {
row--;
}
}
int col = static_cast<int>(thepixel.second);
if (col >= m_ncols) {
fail = (p.y() - m_pitchy * m_ncols > tol);
if (!fail) {
col--;
}
}
if (fail) {
throw cms::Exception("RectangularMTDTopology")
<< "Incorrect pixel id! r/c " << std::fixed << std::setw(2) << row << " / " << std::fixed << std::setw(2) << col
<< " with max " << std::fixed << std::setw(2) << m_nrows << " / " << std::fixed << std::setw(2) << m_ncols
<< " for LocalPoint " << std::fixed << std::setw(8) << std::setprecision(4) << p.x() << " , " << std::fixed
<< std::setw(8) << std::setprecision(4) << p.y() << " pixel " << std::fixed << std::setw(8)
<< std::setprecision(4) << thepixel.first << " , " << std::fixed << std::setw(8) << std::setprecision(4)
<< thepixel.second << " deltas " << p.x() - m_pitchx * m_nrows << " , " << p.y() - m_pitchy * m_ncols;
}
return std::pair<int, int>(row, col);
}
//The following lines check whether the point is actually out of the active pixel area.
bool RectangularMTDTopology::isInPixel(const LocalPoint& p) const {
bool isInside = true;
const auto& thepixel = pixel(p);
const int ixbin = static_cast<int>(thepixel.first);
const int iybin = static_cast<int>(thepixel.second);
const float fractionX = thepixel.first - ixbin;
const float fractionY = thepixel.second - iybin;
if ((fractionX > 1.0 - m_GAPxInterpadFrac || fractionX < m_GAPxInterpadFrac) ||
(ixbin == 0 && fractionX < m_GAPxBorderFrac) || (ixbin == m_nrows - 1 && fractionX > 1.0 - m_GAPxBorderFrac)) {
isInside = false;
}
if ((fractionY > 1.0 - m_GAPyInterpadFrac || fractionY < m_GAPyInterpadFrac) ||
(iybin == 0 && fractionY < m_GAPyBorderFrac) || (iybin == m_ncols - 1 && fractionY > 1.0 - m_GAPyBorderFrac)) {
isInside = false;
}
return isInside;
}
//----------------------------------------------------------------------
// Topology interface, go from Measurement to Local corrdinates
// pixel coordinates (mp) -> cm (LocalPoint)
LocalPoint RectangularMTDTopology::localPosition(const MeasurementPoint& mp) const {
float mpy = mp.y(); // measurements
float mpx = mp.x();
float lpY = localY(mpy);
float lpX = localX(mpx);
// Return it as a LocalPoint
return LocalPoint(lpX, lpY);
}
//--------------------------------------------------------------------
//
// measuremet to local transformation for X coordinate
float RectangularMTDTopology::localX(const float mpx) const {
// The final position in local coordinates
float lpX = (mpx + 0.5f) * m_pitchx + m_xoffset;
return lpX;
}
float RectangularMTDTopology::localY(const float mpy) const {
// The final position in local coordinates
float lpY = (mpy + 0.5f) * m_pitchy + m_yoffset;
return lpY;
}
///////////////////////////////////////////////////////////////////
// Get hit errors in LocalPoint coordinates (cm)
LocalError RectangularMTDTopology::localError(const MeasurementPoint& mp, const MeasurementError& me) const {
return LocalError(me.uu() * float(m_pitchx * m_pitchx), 0, me.vv() * float(m_pitchy * m_pitchy));
}
/////////////////////////////////////////////////////////////////////
// Get errors in pixel pitch units.
MeasurementError RectangularMTDTopology::measurementError(const LocalPoint& lp, const LocalError& le) const {
return MeasurementError(le.xx() / float(m_pitchx * m_pitchx), 0, le.yy() / float(m_pitchy * m_pitchy));
}
|