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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
|
#ifndef Geometry_TrackerGeometryBuilder_RectangularPixelPhase2Topology_H
#define Geometry_TrackerGeometryBuilder_RectangularPixelPhase2Topology_H
/**
* Topology for rectangular pixel detector with BIG pixels.
*/
// Re-written for phase-2 pixels.
// E. Migliore INFN/Universita Torino 2023/11
// The bigger pixels are on the ROC boundries.
// G. Giurgiu 11/27/06 ---------------------------------------------
// Check whether the pixel is at the edge of the module by adding the
// following functions (ixbin and iybin are the pixel row and column
// inside the module):
// bool isItEdgePixelInX (int ixbin)
// bool isItEdgePixelInY (int iybin)
// bool isItEdgePixel (int ixbin, int iybin)
// ------------------------------------------------------------------
// Add the individual measurement to local trasformations classes 01/07 d.k.
// ------------------------------------------------------------------
// Add big pixel flags for cluster range 15/3/07 V.Chiochia
#include "Geometry/CommonTopologies/interface/PixelTopology.h"
#include "DataFormats/SiPixelDetId/interface/PixelChannelIdentifier.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
class RectangularPixelPhase2Topology final : public PixelTopology {
public:
// Constructor, initilize
RectangularPixelPhase2Topology(int nrows,
int ncols,
float pitchx,
float pitchy,
int ROWS_PER_ROC, // Num of Rows per ROC
int COLS_PER_ROC, // Num of Cols per ROC
int BIG_PIX_PER_ROC_X, // in x direction, rows
int BIG_PIX_PER_ROC_Y, // in y direction, cols
float BIG_PIX_PITCH_X,
float BIG_PIX_PITCH_Y,
int ROCS_X,
int ROCS_Y)
: m_pitchx(pitchx),
m_pitchy(pitchy),
m_nrows(nrows),
m_ncols(ncols),
m_ROWS_PER_ROC(ROWS_PER_ROC), // Num of Rows per ROC
m_COLS_PER_ROC(COLS_PER_ROC), // Num of Cols per ROC
m_BIG_PIX_PER_ROC_X(BIG_PIX_PER_ROC_X), //
m_BIG_PIX_PER_ROC_Y(BIG_PIX_PER_ROC_Y), //
m_BIG_PIX_PITCH_X(BIG_PIX_PITCH_X),
m_BIG_PIX_PITCH_Y(BIG_PIX_PITCH_Y),
m_ROCS_X(ROCS_X), //
m_ROCS_Y(ROCS_Y) //
{
// Calculate the edge of the active sensor with respect to the center,
// that is simply the half-size.
// Take into account large pixels
m_xoffset = -(
(m_nrows / 2 - m_BIG_PIX_PER_ROC_X) * m_pitchx +
m_BIG_PIX_PER_ROC_X *
m_BIG_PIX_PITCH_X); // assuming the big pixel pitch is well computed it gets always in the middle regardless the number of big pixel. Quad is 670*0.025 + 2*0.0875; double is 336* 0.025; 3D is 336*0.025; old geom is 672*faxe x pitch
m_yoffset = -((m_ncols / 2 - m_BIG_PIX_PER_ROC_Y) * m_pitchy + m_BIG_PIX_PER_ROC_Y * m_BIG_PIX_PITCH_Y);
LogDebug("RectangularPixelPhase2Topology")
<< "nrows " << m_nrows << ", ncols " << m_ncols << ", pitchx " << m_pitchx << ", pitchy " << m_pitchy
<< ", xoffset " << m_xoffset << ", yoffset " << m_yoffset << ", BIG_PIX_PER_ROC_X " << BIG_PIX_PER_ROC_X
<< ", BIG_PIX_PER_ROC_Y " << BIG_PIX_PER_ROC_Y << ", BIG_PIX_PITCH_X " << BIG_PIX_PITCH_X
<< ", BIG_PIX_PITCH_Y " << BIG_PIX_PITCH_Y << ", ROWS_PER_ROC " << ROWS_PER_ROC << ", COLS_PER_ROC "
<< COLS_PER_ROC << ", ROCS_X " << ROCS_X << ", ROCS_Y " << ROCS_Y << "\nNROWS " << m_ROWS_PER_ROC * m_ROCS_X
<< ", NCOL " << m_COLS_PER_ROC * m_ROCS_Y;
}
// Topology interface, go from Masurement to Local corrdinates
// pixel coordinates (mp) -> cm (LocalPoint)
LocalPoint localPosition(const MeasurementPoint& mp) const override;
// Transform LocalPoint to Measurement. Call pixel().
MeasurementPoint measurementPosition(const LocalPoint& lp) const override {
std::pair<float, float> p = pixel(lp);
return MeasurementPoint(p.first, p.second);
}
// PixelTopology interface.
// Transform LocalPoint in cm to measurement in pitch units.
std::pair<float, float> pixel(const LocalPoint& p) const override;
// Errors
// Error in local (cm) from the masurement errors
LocalError localError(const MeasurementPoint&, const MeasurementError&) const override;
// Errors in pitch units from localpoint error (in cm)
MeasurementError measurementError(const LocalPoint&, const LocalError&) const override;
//-------------------------------------------------------------
// Transform LocalPoint to channel. Call pixel()
//
int channel(const LocalPoint& lp) const override {
std::pair<float, float> p = pixel(lp);
return PixelChannelIdentifier::pixelToChannel(int(p.first), int(p.second));
}
//-------------------------------------------------------------
// Transform measurement to local coordinates individually in each dimension
//
float localX(const float mpX) const override;
float localY(const float mpY) const override;
//-------------------------------------------------------------
// Return the BIG pixel information for a given pixel (assuming they are always at the edge between two CROCs)
//
bool isItBigPixelInX(const int ixbin) const override {
bool no_big_pixel = (m_BIG_PIX_PER_ROC_X == 0);
if (!no_big_pixel)
no_big_pixel = std::abs((ixbin - m_nrows / 2) + 0.5) > m_BIG_PIX_PER_ROC_X;
return !no_big_pixel;
}
bool isItBigPixelInY(const int iybin) const override {
bool no_big_pixel = (m_BIG_PIX_PER_ROC_Y == 0);
if (!no_big_pixel)
no_big_pixel = std::abs((iybin - m_ncols / 2) + 0.5) > m_BIG_PIX_PER_ROC_Y;
return !no_big_pixel;
}
float pixelFractionInX(const int ixbin) const override {
bool no_big_pixel = (m_BIG_PIX_PER_ROC_X == 0);
if (no_big_pixel) {
return 1.0f;
} else {
if (((m_nrows / 2 - m_BIG_PIX_PER_ROC_X) <= ixbin) &&
(ixbin < (m_nrows / 2 - m_BIG_PIX_PER_ROC_X + m_BIG_PIX_PER_ROC_X * m_nrows / m_ROWS_PER_ROC))) {
return float(m_BIG_PIX_PITCH_X / m_pitchx);
} else {
return 1.0f;
}
}
}
float pixelFractionInY(const int iybin) const override {
bool no_big_pixel = (m_BIG_PIX_PER_ROC_Y == 0);
if (no_big_pixel) {
return 1.0f;
} else {
if (((m_ncols / 2 - m_BIG_PIX_PER_ROC_Y) <= iybin) &&
(iybin < (m_ncols / 2 - m_BIG_PIX_PER_ROC_Y + m_BIG_PIX_PER_ROC_Y * m_ncols / m_COLS_PER_ROC))) {
return float(m_BIG_PIX_PITCH_Y / m_pitchy);
} else {
return 1.0f;
}
}
}
//-------------------------------------------------------------
// Return BIG pixel flag in a given pixel range (assuming they are always at the edge between two CROCs)
//
bool containsBigPixelInX(int ixmin, int ixmax) const override {
return containsBigPixel(ixmin, ixmax, m_nrows, m_BIG_PIX_PER_ROC_X);
}
bool containsBigPixelInY(int iymin, int iymax) const override {
return containsBigPixel(iymin, iymax, m_ncols, m_BIG_PIX_PER_ROC_Y);
}
bool bigpixelsX() const override { return false; }
bool bigpixelsY() const override { return false; }
//-------------------------------------------------------------
// Check whether the pixel is at the edge of the module
//
bool isItEdgePixelInX(int ixbin) const override { return ((ixbin == 0) | (ixbin == (m_nrows - 1))); }
bool isItEdgePixelInY(int iybin) const override { return ((iybin == 0) | (iybin == (m_ncols - 1))); }
bool isItEdgePixel(int ixbin, int iybin) const override {
return (isItEdgePixelInX(ixbin) || isItEdgePixelInY(iybin));
}
//------------------------------------------------------------------
// Return pitch
std::pair<float, float> pitch() const override { return std::pair<float, float>(float(m_pitchx), float(m_pitchy)); }
// Return number of rows
int nrows() const override { return (m_nrows); }
// Return number of cols
int ncolumns() const override { return (m_ncols); }
// mlw Return number of ROCS Y
int rocsY() const override { return m_ROCS_Y; }
// mlw Return number of ROCS X
int rocsX() const override { return m_ROCS_X; }
// mlw Return number of rows per roc
int rowsperroc() const override { return m_ROWS_PER_ROC; }
// mlw Return number of cols per roc
int colsperroc() const override { return m_COLS_PER_ROC; }
int bigpixperrocX() const { return m_BIG_PIX_PER_ROC_X; }
int bigpixperrocY() const { return m_BIG_PIX_PER_ROC_Y; }
float xoffset() const { return m_xoffset; }
float yoffset() const { return m_yoffset; }
float pitchbigpixelX() const { return m_BIG_PIX_PITCH_X; }
float pitchbigpixelY() const { return m_BIG_PIX_PITCH_Y; }
private:
float m_pitchx;
float m_pitchy;
float m_xoffset;
float m_yoffset;
int m_nrows;
int m_ncols;
int m_ROWS_PER_ROC;
int m_COLS_PER_ROC;
int m_BIG_PIX_PER_ROC_X;
int m_BIG_PIX_PER_ROC_Y;
float m_BIG_PIX_PITCH_X;
float m_BIG_PIX_PITCH_Y;
int m_ROCS_X;
int m_ROCS_Y;
bool containsBigPixel(int iMin, int iMax, int nPxTot, int nPxBigPerROC) const {
// nPxTot/2 should lie in the upper half of the dimension
auto firstBigPixel = nPxTot / 2 - nPxBigPerROC;
auto lastBigPixel = nPxTot / 2 - 1 + nPxBigPerROC;
// the interval contains no big pixel when either of the following is met:
// - there are no big pixels
// - the whole interval lies to the right of the big pixel chunk
// - the whole interval lies to the left of the big pixel chunk
bool noBigPixel = (nPxBigPerROC == 0) || (iMin > lastBigPixel) || (iMax < firstBigPixel);
return !noBigPixel;
}
};
#endif
|