ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
DetectorDescription
ReadoutGeometryBase
src
PixelDiodeMatrix.cxx
Go to the documentation of this file.
1
/*
2
Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3
*/
4
5
#include "
ReadoutGeometryBase/PixelDiodeMatrix.h
"
6
#include "
ReadoutGeometryBase/SiCellId.h
"
7
#include "
TrkEventPrimitives/ParamDefs.h
"
8
9
#include <cassert>
10
#include <utility>
11
12
namespace
InDetDD
{
13
14
std::shared_ptr<const PixelDiodeMatrix>
PixelDiodeMatrix::construct
(
double
phiWidth
,
double
etaWidth
)
15
{
16
class
Helper :
public
PixelDiodeMatrix
{};
17
std::shared_ptr<PixelDiodeMatrix> ptr = std::make_shared<Helper>();
18
ptr->initialize(
phiWidth
,
etaWidth
);
19
return
ptr;
20
}
21
22
void
PixelDiodeMatrix::initialize
(
double
phiWidth
,
double
etaWidth
)
23
{
24
m_phiWidth
=
phiWidth
;
25
m_phiWidthInverse
= 1. /
phiWidth
;
26
m_etaWidth
=
etaWidth
;
27
m_etaWidthInverse
= 1. /
etaWidth
;
28
m_phiCells
= 1;
29
m_etaCells
= 1;
30
m_direction
=
phiDir
;
// Irrelevant
31
m_numCells
= 0;
32
m_lowerCell
=
nullptr
;
33
m_middleCells
=
nullptr
;
34
m_upperCell
=
nullptr
;
35
m_singleCell
=
true
;
36
}
37
38
std::shared_ptr<const PixelDiodeMatrix>
PixelDiodeMatrix::construct
(
Direction
direction,
// phi or eta
39
std::shared_ptr<const PixelDiodeMatrix> lowerCell,
40
std::shared_ptr<const PixelDiodeMatrix> middleCells,
41
int
numCells,
42
std::shared_ptr<const PixelDiodeMatrix> upperCell)
43
{
44
class
Helper :
public
PixelDiodeMatrix
{};
45
std::shared_ptr<PixelDiodeMatrix> ptr = std::make_shared<Helper>();
46
ptr->initialize(direction,
47
std::move(lowerCell),
48
std::move(middleCells),
49
numCells,
50
std::move(upperCell));
51
return
ptr;
52
}
53
54
void
PixelDiodeMatrix::initialize
(
Direction
direction,
// phi or eta
55
std::shared_ptr<const PixelDiodeMatrix> lowerCell,
56
std::shared_ptr<const PixelDiodeMatrix> middleCells,
57
int
numCells,
58
std::shared_ptr<const PixelDiodeMatrix> upperCell)
59
{
60
m_phiWidth
= 0;
61
m_etaWidth
= 0;
62
m_phiCells
= 0;
63
m_etaCells
= 0;
64
m_direction
= direction;
65
m_numCells
= numCells;
66
m_lowerCell
= std::move(lowerCell);
67
m_middleCells
= std::move(middleCells);
68
m_upperCell
= std::move(upperCell);
69
m_singleCell
=
false
;
70
71
// middleCells must be non zero.
72
assert(
m_middleCells
);
73
74
if
(
m_direction
==
phiDir
) {
75
76
// In eta direction widths must be all the same.
77
if
(
m_middleCells
){
78
m_etaWidth
=
m_middleCells
->etaWidth();
79
m_etaCells
=
m_middleCells
->etaCells();
80
}
81
// Check lower and upper are consistent
82
// TODO.
83
84
if
(
m_lowerCell
) {
85
m_phiWidth
+=
m_lowerCell
->phiWidth();
86
m_phiCells
+=
m_lowerCell
->phiCells();
87
}
88
89
if
(
m_middleCells
){
90
m_phiWidth
+=
m_numCells
*
m_middleCells
->phiWidth();
91
m_phiCells
+=
m_numCells
*
m_middleCells
->phiCells();
92
}
93
94
if
(
m_upperCell
) {
95
m_phiWidth
+=
m_upperCell
->phiWidth();
96
m_phiCells
+=
m_upperCell
->phiCells();
97
}
98
99
}
else
{
// eta Direction
100
101
// In phi direction widths must be all the same.
102
if
(
m_middleCells
){
103
m_phiWidth
=
m_middleCells
->phiWidth();
104
m_phiCells
=
m_middleCells
->phiCells();
105
}
106
// Check lower and upper are consistent
107
// TODO.
108
109
if
(
m_lowerCell
) {
110
m_etaWidth
+=
m_lowerCell
->etaWidth();
111
m_etaCells
+=
m_lowerCell
->etaCells();
112
}
113
114
if
(
m_middleCells
){
115
m_etaWidth
+=
m_numCells
*
m_middleCells
->etaWidth();
116
m_etaCells
+=
m_numCells
*
m_middleCells
->etaCells();
117
}
118
119
if
(
m_upperCell
) {
120
m_etaWidth
+=
m_upperCell
->etaWidth();
121
m_etaCells
+=
m_upperCell
->etaCells();
122
}
123
124
}
125
126
m_phiWidthInverse
= 1. /
m_phiWidth
;
127
m_etaWidthInverse
= 1. /
m_etaWidth
;
128
}
129
130
const
PixelDiodeMatrix
*
131
PixelDiodeMatrix::cellIdOfPosition
(
const
Amg::Vector2D
& relPosition,
SiCellId
& cellId)
const
132
151
152
{
153
using
Trk::distPhi
;
154
using
Trk::distEta
;
155
156
if
(
m_singleCell
) {
157
return
this
;
158
}
159
160
double
relPosDir = 0;
// Relative position along m_direction
161
int
startIndex = 0;
162
double
pitch = 0;
163
double
pitchInverse = 0;
164
int
middleCells = 0;
165
166
if
(
m_direction
==
phiDir
) {
167
168
relPosDir = relPosition[
distPhi
];
169
pitch =
m_middleCells
->phiWidth();
170
pitchInverse =
m_middleCells
->phiWidthInverse();
171
middleCells =
m_middleCells
->phiCells();
172
173
if
(
m_lowerCell
) {
174
if
(relPosDir < m_lowerCell->
phiWidth
()) {
175
return
m_lowerCell
->cellIdOfPosition(relPosition, cellId);
176
}
else
{
177
relPosDir -=
m_lowerCell
->phiWidth();
178
startIndex +=
m_lowerCell
->phiCells();
179
}
180
}
181
}
else
{
// etaDir
182
183
relPosDir = relPosition[
distEta
];
184
pitch =
m_middleCells
->etaWidth();
185
pitchInverse =
m_middleCells
->etaWidthInverse();
186
middleCells =
m_middleCells
->etaCells();
187
188
if
(
m_lowerCell
) {
189
if
(relPosDir < m_lowerCell->
etaWidth
()) {
190
return
m_lowerCell
->cellIdOfPosition(relPosition, cellId);
191
}
else
{
192
relPosDir -=
m_lowerCell
->etaWidth();
193
startIndex +=
m_lowerCell
->etaCells();
194
}
195
}
196
}
197
198
199
int
index
= relPosDir * pitchInverse;
200
201
const
PixelDiodeMatrix
*nextCell{};
202
203
bool
outOfBounds =
index
>=
m_numCells
;
204
if
(
m_upperCell
!=
nullptr
&& outOfBounds) {
205
// We are in the upper cell.
206
index
=
m_numCells
;
207
nextCell =
m_upperCell
.get();
208
}
else
{
209
// We are in the middle cells
210
// Make sure its in range (in case of rounding errors)
211
if
(outOfBounds)
index
=
m_numCells
- 1;
212
nextCell =
m_middleCells
.get();
213
}
214
215
if
(
index
> 0) {
// Make sure its in range (in case of rounding errors)
216
relPosDir -=
index
* pitch;
217
startIndex +=
index
* middleCells;
218
}
219
220
int
newPhiIndex = cellId.phiIndex();
221
int
newEtaIndex = cellId.etaIndex();
222
const
PixelDiodeMatrix
*cell{};
223
224
if
(
m_direction
==
phiDir
) {
225
if
(nextCell->
singleCell
()) {
226
newPhiIndex += startIndex;
227
cell = nextCell;
228
}
else
{
229
Amg::Vector2D
newRelPos(relPosDir, relPosition[
distEta
]);
230
SiCellId
relId(0,0);
231
cell = nextCell->
cellIdOfPosition
(newRelPos, relId);
232
newPhiIndex += startIndex + relId.
phiIndex
();
233
newEtaIndex += relId.
etaIndex
();
234
}
235
}
else
{
236
if
(nextCell->
singleCell
()) {
237
newEtaIndex += startIndex;
238
cell = nextCell;
239
}
else
{
240
Amg::Vector2D
newRelPos(relPosition[
distPhi
], relPosDir);
241
SiCellId
relId(0,0);
242
cell = nextCell->
cellIdOfPosition
(newRelPos, relId);
243
newPhiIndex += relId.
phiIndex
();
244
newEtaIndex += startIndex + relId.
etaIndex
();
245
}
246
}
247
248
cellId =
SiCellId
(newPhiIndex, newEtaIndex);
249
return
cell;
250
}
251
252
253
254
const
PixelDiodeMatrix
*
255
PixelDiodeMatrix::positionOfCell
(
const
PixelDiodeMatrix
*matrix,
const
SiCellId
& cellId,
Amg::Vector2D
& dest_position)
256
257
271
272
{
273
using
Trk::distPhi
;
274
using
Trk::distEta
;
275
Amg::Vector2D
position{
276
-matrix->phiHalfWidth(),
277
-matrix->etaHalfWidth()
278
};
279
280
int
rel_phi_index = cellId.
phiIndex
();
281
int
rel_eta_index = cellId.
etaIndex
();
282
for
( ;!matrix->m_singleCell; ) {
283
284
int
relIndex = 0;
// Relative index along m_direction
285
double
pitch = 0;
286
int
nMiddleCells = 0;
287
double
startPos = 0;
288
const
auto
direction = matrix->m_direction;
289
290
if
(direction ==
PixelDiodeMatrix::phiDir
) {
291
292
relIndex = rel_phi_index;
293
294
const
PixelDiodeMatrix
*lowerCell = matrix->m_lowerCell.get();
295
if
(lowerCell) {
296
if
(relIndex < lowerCell->
phiCells
()) {
297
matrix = lowerCell;
298
continue
;
299
}
else
{
300
relIndex -= lowerCell->
phiCells
();
301
startPos += lowerCell->
phiWidth
();
302
}
303
}
304
const
PixelDiodeMatrix
*middleCells = matrix->m_middleCells.get();
305
assert(middleCells);
306
pitch = middleCells->
phiWidth
();
307
nMiddleCells = middleCells->
phiCells
();
308
309
}
else
{
// etaDir
310
311
relIndex = rel_eta_index;
312
const
PixelDiodeMatrix
*lowerCell = matrix->m_lowerCell.get();
313
if
(lowerCell) {
314
if
(relIndex < lowerCell->
etaCells
()) {
315
matrix = lowerCell;
316
continue
;
317
}
else
{
318
relIndex -= lowerCell->
etaCells
();
319
startPos += lowerCell->
etaWidth
();
320
}
321
}
322
const
PixelDiodeMatrix
*middleCells = matrix->m_middleCells.get();
323
assert(middleCells);
324
pitch = middleCells->
etaWidth
();
325
nMiddleCells = middleCells->
etaCells
();
326
327
}
328
329
int
index
= std::min(relIndex / nMiddleCells,matrix->m_numCells);
// @TODO upper bound correct ?
330
relIndex -=
index
* nMiddleCells;
331
startPos +=
index
* pitch;
332
333
matrix = (matrix->m_upperCell &&
index
== matrix->m_numCells ) ? matrix->m_upperCell.get() : matrix->m_middleCells.get();
334
335
if
(direction ==
PixelDiodeMatrix::phiDir
) {
336
rel_phi_index = relIndex;
337
position[
distPhi
] += startPos;
338
}
else
{
339
rel_eta_index = relIndex;
340
position[
distEta
] += startPos;
341
}
342
}
343
position[
distPhi
] += matrix->phiHalfWidth();
344
position[
distEta
] += matrix->etaHalfWidth();
345
dest_position = position;
346
return
matrix;
347
}
348
349
std::string
350
PixelDiodeMatrix::createDebugStringRepr
(
unsigned
int
level)
const
351
{
352
std::string prefix(level,
' '
);
353
354
// base case: single cell
355
if
(
m_singleCell
) {
356
std::string cellSize =
""
;
357
cellSize += prefix +
"phi: "
+ std::to_string(
m_phiWidth
) +
"\n"
;
358
cellSize += prefix +
"eta: "
+ std::to_string(
m_etaWidth
) +
"\n"
;
359
return
cellSize;
360
}
361
362
std::string cellContent =
""
;
363
364
if
(
m_lowerCell
==
nullptr
&&
m_middleCells
==
nullptr
&&
m_upperCell
==
nullptr
) {
365
cellContent += prefix +
"completly empty (WARNING: there should always be at least one cell!)\n"
;
366
return
cellContent;
367
}
368
369
cellContent += prefix +
"direction: "
;
370
if
(
m_direction
==
phiDir
) { cellContent +=
"phi\n"
; }
371
else
if
(
m_direction
==
etaDir
) { cellContent +=
"eta\n"
; }
372
else
{ cellContent +=
"unknown\n"
; }
373
374
// recursive call for nested cells
375
if
(
m_lowerCell
!=
nullptr
) {
376
cellContent += prefix +
"lowerCell: \n"
;
377
cellContent +=
m_lowerCell
->createDebugStringRepr(level + 1);
378
}
379
if
(
m_middleCells
!=
nullptr
) {
380
cellContent += prefix +
"middleCells: "
+ std::to_string(
m_numCells
) +
"x :\n"
;
381
cellContent +=
m_middleCells
->createDebugStringRepr(level + 1);
382
}
383
if
(
m_upperCell
!=
nullptr
) {
384
cellContent += prefix +
"upperCell: \n"
;
385
cellContent +=
m_upperCell
->createDebugStringRepr(level + 1);
386
}
387
388
return
cellContent;
389
}
390
391
}
// end namespace
ParamDefs.h
PixelDiodeMatrix.h
SiCellId.h
InDetDD::PixelDiodeMatrix
Class used to describe the segmentation of the pixel and allow for conversion between cell id and pos...
Definition
PixelDiodeMatrix.h:93
InDetDD::PixelDiodeMatrix::m_upperCell
std::shared_ptr< const PixelDiodeMatrix > m_upperCell
Definition
PixelDiodeMatrix.h:199
InDetDD::PixelDiodeMatrix::cellIdOfPosition
const PixelDiodeMatrix * cellIdOfPosition(const Amg::Vector2D &position, SiCellId &cellId) const
Return cell Id corresponding to a relative position within the matrix.
Definition
PixelDiodeMatrix.cxx:131
InDetDD::PixelDiodeMatrix::m_middleCells
std::shared_ptr< const PixelDiodeMatrix > m_middleCells
Definition
PixelDiodeMatrix.h:198
InDetDD::PixelDiodeMatrix::m_etaWidth
double m_etaWidth
Definition
PixelDiodeMatrix.h:191
InDetDD::PixelDiodeMatrix::createDebugStringRepr
std::string createDebugStringRepr() const
Create debug representation.
Definition
PixelDiodeMatrix.h:249
InDetDD::PixelDiodeMatrix::PixelDiodeMatrix
PixelDiodeMatrix()
Hidden constructor.
Definition
PixelDiodeMatrix.h:161
InDetDD::PixelDiodeMatrix::m_etaWidthInverse
double m_etaWidthInverse
Definition
PixelDiodeMatrix.h:192
InDetDD::PixelDiodeMatrix::m_phiWidthInverse
double m_phiWidthInverse
Definition
PixelDiodeMatrix.h:190
InDetDD::PixelDiodeMatrix::m_etaCells
int m_etaCells
Definition
PixelDiodeMatrix.h:194
InDetDD::PixelDiodeMatrix::m_singleCell
bool m_singleCell
Definition
PixelDiodeMatrix.h:200
InDetDD::PixelDiodeMatrix::singleCell
bool singleCell() const
Query wether the matrix is just a single cell.
Definition
PixelDiodeMatrix.h:244
InDetDD::PixelDiodeMatrix::m_direction
Direction m_direction
Definition
PixelDiodeMatrix.h:195
InDetDD::PixelDiodeMatrix::initialize
void initialize(double phiWidth, double etaWidth)
Initialize for just a single cell.
Definition
PixelDiodeMatrix.cxx:22
InDetDD::PixelDiodeMatrix::construct
static std::shared_ptr< const PixelDiodeMatrix > construct(double phiWidth, double etaWidth)
Construct method for just a single cell.
Definition
PixelDiodeMatrix.cxx:14
InDetDD::PixelDiodeMatrix::phiCells
int phiCells() const
Number of cells in phi (x) direction.
Definition
PixelDiodeMatrix.h:234
InDetDD::PixelDiodeMatrix::etaCells
int etaCells() const
Number of cells in eta (y) direction.
Definition
PixelDiodeMatrix.h:239
InDetDD::PixelDiodeMatrix::m_phiCells
int m_phiCells
Definition
PixelDiodeMatrix.h:193
InDetDD::PixelDiodeMatrix::positionOfCell
const PixelDiodeMatrix * positionOfCell(const SiCellId &cellId, Amg::Vector2D &position) const
Search diode matching the given cell id and compute its position.
Definition
PixelDiodeMatrix.h:255
InDetDD::PixelDiodeMatrix::etaWidth
double etaWidth() const
Width in eta (y) direction.
Definition
PixelDiodeMatrix.h:219
InDetDD::PixelDiodeMatrix::m_phiWidth
double m_phiWidth
Definition
PixelDiodeMatrix.h:189
InDetDD::PixelDiodeMatrix::m_numCells
int m_numCells
Definition
PixelDiodeMatrix.h:196
InDetDD::PixelDiodeMatrix::phiWidth
double phiWidth() const
Width in phi (x) direction.
Definition
PixelDiodeMatrix.h:204
InDetDD::PixelDiodeMatrix::Direction
Direction
Definition
PixelDiodeMatrix.h:97
InDetDD::PixelDiodeMatrix::etaDir
@ etaDir
Definition
PixelDiodeMatrix.h:97
InDetDD::PixelDiodeMatrix::phiDir
@ phiDir
Definition
PixelDiodeMatrix.h:97
InDetDD::PixelDiodeMatrix::m_lowerCell
std::shared_ptr< const PixelDiodeMatrix > m_lowerCell
Definition
PixelDiodeMatrix.h:197
InDetDD::SiCellId
Identifier for the strip or pixel cell.
Definition
SiCellId.h:29
InDetDD::SiCellId::phiIndex
int phiIndex() const
Get phi index. Equivalent to strip().
Definition
SiCellId.h:122
InDetDD::SiCellId::etaIndex
int etaIndex() const
Get eta index.
Definition
SiCellId.h:114
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition
GeoPrimitives.h:49
InDetDD
Message Stream Member.
Definition
FakeTrackBuilder.h:8
InDetDD::distEta
@ distEta
readout for silicon
Definition
ParamDefs.h:51
InDetDD::distPhi
@ distPhi
Definition
ParamDefs.h:50
Trk::distEta
@ distEta
readout for silicon
Definition
ParamDefs.h:51
Trk::distPhi
@ distPhi
Definition
ParamDefs.h:50
index
Definition
index.py:1
Generated on
for ATLAS Offline Software by
1.17.0