ATLAS Offline Software
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 
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 {
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;
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 
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 *
256 
257 
258 
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
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
InDetDD::PixelDiodeMatrix::phiWidth
double phiWidth() const
Width in phi (x) direction.
Definition: PixelDiodeMatrix.h:204
InDetDD::PixelDiodeMatrix::m_upperCell
std::shared_ptr< const PixelDiodeMatrix > m_upperCell
Definition: PixelDiodeMatrix.h:199
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
InDetDD::PixelDiodeMatrix::m_etaCells
int m_etaCells
Definition: PixelDiodeMatrix.h:194
AsgConfigHelper::Helper
std::vector< T > Helper(const std::string &input, TEnv &env)
Definition: AsgEGammaConfigHelper.cxx:83
InDetDD::PixelDiodeMatrix::m_singleCell
bool m_singleCell
Definition: PixelDiodeMatrix.h:200
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
index
Definition: index.py:1
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
InDetDD::PixelDiodeMatrix::etaWidth
double etaWidth() const
Width in eta (y) direction.
Definition: PixelDiodeMatrix.h:219
InDetDD::PixelDiodeMatrix::createDebugStringRepr
std::string createDebugStringRepr() const
Create debug representation.
Definition: PixelDiodeMatrix.h:249
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::SiCellId::phiIndex
int phiIndex() const
Get phi index. Equivalent to strip().
Definition: SiCellId.h:122
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
InDetDD::PixelDiodeMatrix::phiCells
int phiCells() const
Number of cells in phi (x) direction.
Definition: PixelDiodeMatrix.h:234
ParamDefs.h
python.iconfTool.models.loaders.level
level
Definition: loaders.py:20
InDetDD::PixelDiodeMatrix::phiDir
@ phiDir
Definition: PixelDiodeMatrix.h:97
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::SiCellId::etaIndex
int etaIndex() const
Get eta index.
Definition: SiCellId.h:114
InDetDD::PixelDiodeMatrix::m_lowerCell
std::shared_ptr< const PixelDiodeMatrix > m_lowerCell
Definition: PixelDiodeMatrix.h:197
Trk::distEta
@ distEta
readout for silicon
Definition: ParamDefs.h:51
InDetDD::PixelDiodeMatrix::m_phiWidthInverse
double m_phiWidthInverse
Definition: PixelDiodeMatrix.h:190
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
checkCorrelInHIST.prefix
dictionary prefix
Definition: checkCorrelInHIST.py:391
Trk::distPhi
@ distPhi
Definition: ParamDefs.h:50
InDetDD::PixelDiodeMatrix::m_etaWidth
double m_etaWidth
Definition: PixelDiodeMatrix.h:191
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
InDetDD::PixelDiodeMatrix::m_phiWidth
double m_phiWidth
Definition: PixelDiodeMatrix.h:189
InDetDD::PixelDiodeMatrix::m_numCells
int m_numCells
Definition: PixelDiodeMatrix.h:196
InDetDD::PixelDiodeMatrix::etaCells
int etaCells() const
Number of cells in eta (y) direction.
Definition: PixelDiodeMatrix.h:239
InDetDD::SiCellId
Definition: SiCellId.h:29
InDetDD::PixelDiodeMatrix::m_middleCells
std::shared_ptr< const PixelDiodeMatrix > m_middleCells
Definition: PixelDiodeMatrix.h:198
PixelDiodeMatrix.h
python.testIfMatch.matrix
matrix
Definition: testIfMatch.py:63
InDetDD::PixelDiodeMatrix::initialize
void initialize(double phiWidth, double etaWidth)
Initialize for just a single cell.
Definition: PixelDiodeMatrix.cxx:22
xAOD::TauJetParameters::numCells
@ numCells
Definition: TauDefs.h:171
InDetDD
Message Stream Member.
Definition: FakeTrackBuilder.h:8
InDetDD::PixelDiodeMatrix::m_direction
Direction m_direction
Definition: PixelDiodeMatrix.h:195
InDetDD::PixelDiodeMatrix::m_etaWidthInverse
double m_etaWidthInverse
Definition: PixelDiodeMatrix.h:192
xAOD::phiWidth
phiWidth
Definition: RingSetConf_v1.cxx:612
SiCellId.h
InDetDD::PixelDiodeMatrix::Direction
Direction
Definition: PixelDiodeMatrix.h:97
InDetDD::PixelDiodeMatrix
Definition: PixelDiodeMatrix.h:93
InDetDD::PixelDiodeMatrix::etaDir
@ etaDir
Definition: PixelDiodeMatrix.h:97