ATLAS Offline Software
PixelDiodeTree.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3  */
5 #include <sstream>
6 #include <iomanip>
7 #include <utility>
8 
9 namespace InDetDD {
10 
12  unsigned int errors=0;
13  constexpr std::array<IndexType,2> axis_offset{1,2};
14  for (std::array<IndexType,4> &a_split : m_subMatrixIndex) {
15  unsigned int n_invalid=0;
16  IndexType good_idx=s_invalid;
17  std::array<std::array<unsigned int,2>,2> n_invalid_halves{};
18  for (unsigned int element_i=0; element_i<a_split.size(); ++element_i) {
19  bool is_invalid = a_split.at(element_i)==s_invalid;
20  unsigned int axis0=element_i/2;
21  unsigned int axis1=element_i%2;
22  n_invalid_halves[0][axis0]+=is_invalid;
23  n_invalid_halves[1][axis1]+=is_invalid;
24  if (is_invalid) ++n_invalid;
25  else { good_idx=a_split[element_i]; }
26  }
27  if (n_invalid==3) {
28  assert( good_idx != s_invalid);
29  for (unsigned int element_i=0; element_i<a_split.size(); ++element_i) {
30  a_split.at(element_i)=good_idx;
31  }
32  }
33  else if (n_invalid==2) {
34  unsigned int element_i=std::numeric_limits<unsigned int>::max();
35  for (unsigned int axis_i=0; axis_i<2; ++axis_i) {
36  for (unsigned int side_i=0; side_i<2; ++side_i) {
37  if (n_invalid_halves[axis_i][side_i]==2 && n_invalid_halves[axis_i][side_i^1]==0) {
38  element_i=axis_offset[axis_i^1]*side_i;
39  IndexType other_element_i = axis_offset[axis_i^1]*(side_i==1 ? -1 : 1);
40  unsigned int element_end_i=element_i+axis_offset[axis_i]*2;
41  for(; element_i<element_end_i; element_i+=axis_offset[axis_i] ) {
42  a_split[ element_i ] = a_split[ element_i + other_element_i] ;
43  }
44  break;
45  }
46  if (element_i != std::numeric_limits<unsigned int>::max()) break;
47  }
48  }
49  if (element_i == std::numeric_limits<unsigned int>::max()) {
50  errors += 2;
51  }
52  }
53  else if (n_invalid!=0) {
54  errors +=2;
55  }
56  }
57 
58  return errors;
59 }
60 
61 void PixelDiodeTree::computeMatrixCorner(const std::array<PixelDiodeTree::CellIndexType,2> &matrix_dim) {
62  assert( matrix_dim[0]>0 && matrix_dim[1]>0);
63  m_matrixDim=matrix_dim;
65  {
66  DiodeProxyWithPosition lower_corner_proxy(diodeProxyFromIdxCachePosition(std::array<CellIndexType,2> {}));
67  m_matrixCorner[0]=lower_corner_proxy.position() - lower_corner_proxy.width()*.5;
68  for (unsigned int axis_i=0; axis_i<2; ++axis_i) {
69  m_matrixCorner[0][axis_i] += tolerance[axis_i];
70  }
71  }
72 
73  {
74  DiodeProxyWithPosition upper_corner_proxy(diodeProxyFromIdxCachePosition(std::array<PixelDiodeTree::CellIndexType,2> {matrix_dim[0]-1,
75  matrix_dim[1]-1}));
76  m_matrixCorner[1]=upper_corner_proxy.position() + upper_corner_proxy.width()*.5 ;
77  for (unsigned int axis_i=0; axis_i<2; ++axis_i) {
78  m_matrixCorner[1][axis_i] -= tolerance[axis_i];
79  }
80  }
82  throw std::logic_error("Logic error! Matrix corner positions do not yield valid indices for this matrix!");
83  }
84 }
85 
86 PixelDiodeTree::Vector2D PixelDiodeTree::computeTolerance(const std::array<PixelDiodeTree::CellIndexType,2> &matrix_dim) const {
88  for (unsigned int axis_i=0; axis_i<2; ++axis_i) {
89  assert( matrix_dim[axis_i]>0 &&
90  static_cast<unsigned int>(std::abs(matrix_dim[axis_i])) < std::numeric_limits<unsigned int>::max());
91  unsigned int bits_i=0;
92  for (; bits_i<16 && 1u<<bits_i < static_cast<unsigned int>(matrix_dim[axis_i])*3; ++bits_i);
93  tolerance[axis_i]=(1u<<bits_i) * std::numeric_limits<PixelDiodeTree::FloatType>::epsilon();
94  }
95  return tolerance;
96 }
97 
98 std::string PixelDiodeTree::debugStringRepr() const {
99  std::stringstream out;
100  if (!m_diodeParam.m_width.empty()) {
101  if ( m_idxSplit.size() != m_posSplit.size()
102  || m_idxSplit.size() != m_subMatrixIndex.size()
103  || m_idxSplit.size() != m_attribute.size()
104  || m_diodeParam.m_width.size() != m_diodeParam.m_invWidth.size()
105  || m_diodeParam.m_width.size() != m_diodeParam.m_attribute.size()) {
106  // should never happer
107  out << "PixelDiodeTree is inconsistent. Expected identical number of elements but has the following "
108  << " container sizes: index-split points : " << m_idxSplit.size()
109  << " position split points : " << m_posSplit.size()
110  << " submatrices : " << m_subMatrixIndex.size()
111  << " attributes : " << m_attribute.size()
112  << "; diodes : width : " << m_diodeParam.m_width.size()
113  << " inverted width : " << m_diodeParam.m_invWidth.size()
114  << " attributes : " << m_diodeParam.m_attribute.size()
115  << ".\n";
116  }
117  else {
118  out << "PixelDiodeTree total width : " << m_diodeParam.m_width[0][0] << "x" << m_diodeParam.m_width[0][1] << " mm^2" << "\n:";
119  std::vector<std::pair<IndexType,unsigned int> > submatrix_stack;
120  submatrix_stack.push_back(std::make_pair(0u,2u));
121  while (!submatrix_stack.empty()) {
122  auto [submatrix_idx, margin] = submatrix_stack.back();
123  submatrix_stack.pop_back();
124  out << std::setw(margin) << ' ';
125  if (submatrix_idx < 0) {
126  if (submatrix_idx!=s_invalid) {
127  unsigned int diode_idx=std::abs(submatrix_idx);
128  if (diode_idx<m_diodeParam.m_width.size()) {
129  out << " diode width " << m_diodeParam.m_width[diode_idx][0] << " x " << m_diodeParam.m_width[diode_idx][1]
130  << " attribute " << std::hex << m_diodeParam.m_attribute[diode_idx] << std::dec << "\n";
131  }
132  }
133  }
134  else if (static_cast<std::size_t>(submatrix_idx) >= m_idxSplit.size()) {
135  out << "Invalid sub-matrix index : " << submatrix_idx << "\n";
136  }
137  else {
138  out << " split at (row,col) " << m_idxSplit[submatrix_idx][0] << " " << m_idxSplit[submatrix_idx][1]
139  << " , position (local-x/-y) " << m_posSplit[submatrix_idx][0] << " " << m_posSplit[submatrix_idx][1]
140  << " attribute " << std::hex << m_attribute[submatrix_idx] << std::dec
141  << " sub-matrices (diodes): ";
142  for (unsigned int split_i=0; split_i<m_subMatrixIndex[submatrix_idx].size(); ++split_i) {
143  out << (split_i==2 ? " | " : " ");
144  if (m_subMatrixIndex[submatrix_idx][split_i] == s_invalid) {
145  out << "-";
146  }
147  else {
148  out << m_subMatrixIndex[submatrix_idx][split_i];
149  }
150  }
151  out << "\n";
152  for (std::array<IndexType,4>::const_reverse_iterator iter = m_subMatrixIndex[submatrix_idx].rbegin();
153  iter != m_subMatrixIndex[submatrix_idx].rend();
154  ++iter) {
155  if (*iter != s_invalid) {
156  submatrix_stack.push_back( std::make_pair( *iter, margin+2));
157  }
158  }
159  }
160  }
161  }
162  }
163  else {
164  out << "PixelDiodeTree with " << m_subMatrixIndex.size() << " has no diodes." << "\n";
165  }
166  return out.str();
167 }
168 }
createLinkingScheme.iter
iter
Definition: createLinkingScheme.py:62
tolerance
constexpr double tolerance
Definition: runMdtGeoComparison.cxx:104
InDetDD::PixelDiodeTree::DiodeProxy::width
const PixelDiodeTree::Vector2D & width() const
get the width stored for this diode.
Definition: PixelDiodeTree.h:195
InDetDD::PixelDiodeTree::DiodeProxyWithPosition::position
const Vector2D & position() const
get the cached position of this diode
Definition: PixelDiodeTree.h:241
InDetDD::PixelDiodeTree::findFromPos
std::array< CellIndexType, 2 > findFromPos(const Vector2D &pos) const
Find a diode by the position relative to the center of the full diode matrix and compute its 2D index...
Definition: PixelDiodeTree.h:282
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
InDetDD::PixelDiodeTree::diodeProxyFromIdxCachePosition
DiodeProxyWithPosition diodeProxyFromIdxCachePosition(const std::array< CellIndexType, 2 > &idx) const
find a diode by its 2D index (row, column) and compute the position of the diode the returned proxy c...
Definition: PixelDiodeTree.h:276
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:70
InDetDD::PixelDiodeTree::m_diodeParam
DiodeParam m_diodeParam
Definition: PixelDiodeTree.h:383
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
InDetDD::PixelDiodeTree::DiodeParam::m_width
std::vector< Vector2D > m_width
Definition: PixelDiodeTree.h:44
InDetDD::PixelDiodeTree::DiodeParam::m_attribute
std::vector< AttributeType > m_attribute
Definition: PixelDiodeTree.h:46
InDetDD::PixelDiodeTree::DiodeProxyWithPosition
A diode proxy which caches the position of a diode.
Definition: PixelDiodeTree.h:230
InDetDD::PixelDiodeTree::cloneSingleSplitsToUnusedHalf
unsigned int cloneSingleSplitsToUnusedHalf()
Clone half with valid split indices to "unused" half with invalid split indices.
Definition: PixelDiodeTree.cxx:11
InDetDD::PixelDiodeTree::DiodeParam::m_invWidth
std::vector< Vector2D > m_invWidth
Definition: PixelDiodeTree.h:45
mergePhysValFiles.errors
list errors
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:42
InDetDD::PixelDiodeTree::computeTolerance
PixelDiodeTree::Vector2D computeTolerance(const std::array< PixelDiodeTree::CellIndexType, 2 > &matrix_dim) const
Compute tolerance to ensure that a position is within the expected cell Due to limited floating point...
Definition: PixelDiodeTree.cxx:86
InDetDD::PixelDiodeTree::computeMatrixCorner
void computeMatrixCorner(const std::array< PixelDiodeTree::CellIndexType, 2 > &matrix_dim)
Compute the effective maximum lower and upper corner positions of the matrix.
Definition: PixelDiodeTree.cxx:61
InDetDD::PixelDiodeTree::m_idxSplit
std::vector< std::array< CellIndexType, 2 > > m_idxSplit
Definition: PixelDiodeTree.h:378
InDetDD::PixelDiodeTree::m_posSplit
std::vector< Vector2D > m_posSplit
Definition: PixelDiodeTree.h:379
tolerance
Definition: suep_shower.h:17
InDetDD::PixelDiodeTree::s_invalid
static constexpr IndexType s_invalid
Definition: PixelDiodeTree.h:40
InDetDD::PixelDiodeTree::debugStringRepr
std::string debugStringRepr() const
Dump the diode tree structure into a string.
Definition: PixelDiodeTree.cxx:98
InDetDD::PixelDiodeTree::Vector2D
Amg::Vector2D Vector2D
Definition: PixelDiodeTree.h:35
InDetDD::PixelDiodeTree::isInsideMatrix
bool isInsideMatrix(const std::array< PixelDiodeTree::IndexType, 2 > &idx) const
Return true if the given index describes a valid location inside the matrix.
Definition: PixelDiodeTree.h:359
InDetDD
Message Stream Member.
Definition: FakeTrackBuilder.h:8
InDetDD::PixelDiodeTree::m_matrixDim
std::array< CellIndexType, 2 > m_matrixDim
Definition: PixelDiodeTree.h:385
InDetDD::PixelDiodeTree::m_attribute
std::vector< AttributeType > m_attribute
Definition: PixelDiodeTree.h:380
InDetDD::PixelDiodeTree::m_subMatrixIndex
std::vector< std::array< IndexType, 4 > > m_subMatrixIndex
Definition: PixelDiodeTree.h:382
columnar::rbegin
auto rbegin() const noexcept
Definition: ObjectRange.h:158
PixelDiodeTree.h
InDetDD::PixelDiodeTree::IndexType
int IndexType
Definition: PixelDiodeTree.h:38
InDetDD::PixelDiodeTree::m_matrixCorner
std::array< Vector2D, 2 > m_matrixCorner
Definition: PixelDiodeTree.h:384