ATLAS Offline Software
PixelDiodeMatrix.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 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 *
255 PixelDiodeMatrix::positionOfCell(const SiCellId & cellId, Amg::Vector2D & position) const
256 
271 
272 {
273  using Trk::distPhi;
274  using Trk::distEta;
275 
276  if (m_singleCell) {
277  position[distPhi] += 0.5*m_phiWidth;
278  position[distEta] += 0.5*m_etaWidth;
279  return this;
280  }
281 
282  int relIndex = 0; // Relative index along m_direction
283  double pitch = 0;
284  int middleCells = 0;
285  double startPos = 0;
286 
287  if (m_direction == phiDir) {
288 
289  relIndex = cellId.phiIndex();
290  pitch = m_middleCells->phiWidth();
291  middleCells = m_middleCells->phiCells();
292 
293  if (m_lowerCell) {
294  if (relIndex < m_lowerCell->phiCells()) {
295  return m_lowerCell->positionOfCell(cellId, position);
296  } else {
297  relIndex -= m_lowerCell->phiCells();
298  startPos += m_lowerCell->phiWidth();
299  }
300  }
301 
302  } else { // etaDir
303 
304  relIndex = cellId.etaIndex();
305  pitch = m_middleCells->etaWidth();
306  middleCells = m_middleCells->etaCells();
307 
308  if (m_lowerCell) {
309  if (relIndex < m_lowerCell->etaCells()) {
310  return m_lowerCell->positionOfCell(cellId, position);
311  } else {
312  relIndex -= m_lowerCell->etaCells();
313  startPos += m_lowerCell->etaWidth();
314  }
315  }
316  }
317 
318  int index = relIndex / middleCells;
319  if (index > m_numCells) index = m_numCells;
320  relIndex -= index * middleCells;
321  startPos += index * pitch;
322 
323  const PixelDiodeMatrix *nextCell{};
324  if (m_upperCell && (index == m_numCells)) {
325  // We are in the upper cell.
326  nextCell = m_upperCell.get();
327  } else {
328  // We are in the middle cells
329  nextCell = m_middleCells.get();
330  }
331 
332  const PixelDiodeMatrix *cell{};
333  if (m_direction == phiDir) {
334  SiCellId relId(relIndex,cellId.etaIndex());
335  position[distPhi] += startPos;
336  cell = nextCell->positionOfCell(relId, position);
337  } else {
338  SiCellId relId(cellId.phiIndex(),relIndex);
339  position[distEta] += startPos;
340  cell = nextCell->positionOfCell(relId, position);
341  }
342 
343  return cell;
344 }
345 
346 std::string
348 {
349  std::string prefix(level, ' ');
350 
351  // base case: single cell
352  if (m_singleCell) {
353  std::string cellSize = "";
354  cellSize += prefix + "phi: " + std::to_string(m_phiWidth) + "\n";
355  cellSize += prefix + "eta: " + std::to_string(m_etaWidth) + "\n";
356  return cellSize;
357  }
358 
359  std::string cellContent = "";
360 
361  if (m_lowerCell == nullptr && m_middleCells == nullptr && m_upperCell == nullptr) {
362  cellContent += prefix + "completly empty (WARNING: there should always be at least one cell!)\n";
363  return cellContent;
364  }
365 
366  cellContent += prefix + "direction: ";
367  if (m_direction == phiDir) { cellContent += "phi\n"; }
368  else if (m_direction == etaDir) { cellContent += "eta\n"; }
369  else { cellContent += "unknown\n"; }
370 
371  // recursive call for nested cells
372  if (m_lowerCell != nullptr) {
373  cellContent += prefix + "lowerCell: \n";
374  cellContent += m_lowerCell->createDebugStringRepr(level + 1);
375  }
376  if (m_middleCells != nullptr) {
377  cellContent += prefix + "middleCells: " + std::to_string(m_numCells) + "x :\n";
378  cellContent += m_middleCells->createDebugStringRepr(level + 1);
379  }
380  if (m_upperCell != nullptr) {
381  cellContent += prefix + "upperCell: \n";
382  cellContent += m_upperCell->createDebugStringRepr(level + 1);
383  }
384 
385  return cellContent;
386 }
387 
388 } // end namespace
InDetDD::PixelDiodeMatrix::phiWidth
double phiWidth() const
Width in phi (x) direction.
Definition: PixelDiodeMatrix.h:190
InDetDD::PixelDiodeMatrix::m_upperCell
std::shared_ptr< const PixelDiodeMatrix > m_upperCell
Definition: PixelDiodeMatrix.h:185
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
InDetDD::PixelDiodeMatrix::m_etaCells
int m_etaCells
Definition: PixelDiodeMatrix.h:180
AsgConfigHelper::Helper
std::vector< T > Helper(const std::string &input, TEnv &env)
Definition: AsgEGammaConfigHelper.cxx:82
InDetDD::PixelDiodeMatrix::m_singleCell
bool m_singleCell
Definition: PixelDiodeMatrix.h:186
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
index
Definition: index.py:1
InDetDD::PixelDiodeMatrix::etaWidth
double etaWidth() const
Width in eta (y) direction.
Definition: PixelDiodeMatrix.h:200
InDetDD::PixelDiodeMatrix::createDebugStringRepr
std::string createDebugStringRepr() const
Create debug representation.
Definition: PixelDiodeMatrix.h:225
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
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:183
Trk::distEta
@ distEta
readout for silicon
Definition: ParamDefs.h:57
InDetDD::PixelDiodeMatrix::m_phiWidthInverse
double m_phiWidthInverse
Definition: PixelDiodeMatrix.h:176
InDetDD::PixelDiodeMatrix::m_phiCells
int m_phiCells
Definition: PixelDiodeMatrix.h:179
InDetDD::PixelDiodeMatrix::positionOfCell
const PixelDiodeMatrix * positionOfCell(const SiCellId &cellId, Amg::Vector2D &position) const
Return position correspong to cell with relative id withing the matrix.
Definition: PixelDiodeMatrix.cxx:255
checkCorrelInHIST.prefix
dictionary prefix
Definition: checkCorrelInHIST.py:391
Trk::distPhi
@ distPhi
Definition: ParamDefs.h:56
InDetDD::PixelDiodeMatrix::m_etaWidth
double m_etaWidth
Definition: PixelDiodeMatrix.h:177
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
InDetDD::PixelDiodeMatrix::m_phiWidth
double m_phiWidth
Definition: PixelDiodeMatrix.h:175
InDetDD::PixelDiodeMatrix::m_numCells
int m_numCells
Definition: PixelDiodeMatrix.h:182
InDetDD::SiCellId
Definition: SiCellId.h:29
InDetDD::PixelDiodeMatrix::m_middleCells
std::shared_ptr< const PixelDiodeMatrix > m_middleCells
Definition: PixelDiodeMatrix.h:184
PixelDiodeMatrix.h
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:181
InDetDD::PixelDiodeMatrix::m_etaWidthInverse
double m_etaWidthInverse
Definition: PixelDiodeMatrix.h:178
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