4#ifndef INDETDD_PIXELDIODETREE_H
5#define INDETDD_PIXELDIODETREE_H
21 template <
typename T_Int,
typename T_Float>
22 inline T_Int intFloor(T_Float val) {
23 bool negative=val<static_cast<T_Float>(0.);
25 return static_cast<T_Int
>(
val)-negative;
52 assert(
m_width.size() < std::numeric_limits<unsigned int>::max());
53 unsigned int idx =
m_width.size();
80 assert( diode_idx > 0 && diode_idx < std::numeric_limits<IndexType>::max());
92 unsigned int split(
const std::array<CellIndexType, 2> &idx_split,
95 unsigned int parent_idx=std::numeric_limits<unsigned int>::max(),
96 unsigned int split_i=0) {
100 unsigned int this_submatrix_idx =
m_idxSplit.size();
108 if (parent_idx != std::numeric_limits<unsigned int>::max()) {
113 return this_submatrix_idx;
117 template <
typename T>
118 std::tuple<IndexType,IndexType, IndexType>
120 const std::vector< T > &
split)
const {
123 unsigned int submatrix_i=0;
124 while (sub_matrix_idx>=0) {
125 assert(
static_cast<std::size_t
>(sub_matrix_idx) <
split.size() );
126 last_sub_matrix_idx=sub_matrix_idx;
127 submatrix_i = (val[0] >=
split[sub_matrix_idx][0]) + (val[1] >=
split[sub_matrix_idx][1])*2;
131 assert(
static_cast<size_t>(std::abs(sub_matrix_idx)) <
m_diodeParam.m_width.size() );
132 return std::make_tuple(last_sub_matrix_idx, std::abs(sub_matrix_idx), submatrix_i);
142 const std::array<CellIndexType,2> &idx)
const {
145 assert( diode_idx>0);
146 assert(
static_cast<unsigned int>(diode_idx) <
m_diodeParam.m_width.size() ) ;
147 assert(
static_cast<unsigned int>(sub_matrix_idx) <
m_idxSplit.size() );
148 for (
unsigned int axis_i=0; axis_i<2; ++axis_i) {
149 assert( axis_i <
m_diodeParam.m_width[diode_idx].size() );
150 pos[axis_i] = (
m_posSplit[sub_matrix_idx][axis_i]
151 + ((idx[axis_i]-
m_idxSplit[sub_matrix_idx][axis_i])
167 std::array<CellIndexType,2> idx;
168 assert( diode_idx>0);
169 assert(
static_cast<unsigned int>(diode_idx) <
m_diodeParam.m_invWidth.size() ) ;
170 assert(
static_cast<unsigned int>(sub_matrix_idx) <
m_idxSplit.size() );
171 assert(
static_cast<unsigned int>(sub_matrix_idx) <
m_posSplit.size() );
172 for (
unsigned int axis_i=0; axis_i<2; ++axis_i) {
173 assert( axis_i <
m_diodeParam.m_invWidth[diode_idx].size() );
175 idx[axis_i] = intFloor<CellIndexType>(
m_idxSplit[sub_matrix_idx][axis_i]
176 + (pos[axis_i]-
m_posSplit[sub_matrix_idx][axis_i])
237 :
DiodeProxy{diodeTree, subMatrixIdx, diodeIdx},
272 return DiodeProxy{
this, sub_matrix_idx, diode_idx};
290 return DiodeProxy{
this, sub_matrix_idx, diode_idx};
308 template <
typename T>
310 if constexpr( std::is_signed_v<T>) {
311 return cell_index>= std::numeric_limits<CellIndexType>::min() && cell_index < std::numeric_limits<CellIndexType>::max();
314 return cell_index < std::numeric_limits<CellIndexType>::max();
319 template <
typename T>
320 static constexpr std::array<PixelDiodeTree::CellIndexType,2>
makeCellIndex(T local_x_idx, T local_y_idx) {
322 return std::array<PixelDiodeTree::CellIndexType,2>{
372 template <
typename T_CellID>
374 const std::array<CellIndexType,2> &max_idx,
375 std::vector<T_CellID > &neighbours);
388template <
typename T_CellID>
390 const std::array<CellIndexType,2> &max_idx,
391 std::vector<T_CellID > &neighbours) {
392 neighbours.reserve(8);
393 std::array<std::array<PixelDiodeTree::CellIndexType,2>,2> outer_idx {
394 std::array<PixelDiodeTree::CellIndexType,2>{idx[0]-1,idx[0]+1},
395 std::array<PixelDiodeTree::CellIndexType,2>{idx[1]-1,idx[1]+1}
398 if (outer_idx[0][0]>=0 && outer_idx[1][0]>=0) neighbours.emplace_back(outer_idx[0][0],outer_idx[1][0]);
399 if ( outer_idx[1][0]>=0) neighbours.emplace_back(idx[0], outer_idx[1][0]);
400 if (outer_idx[0][1]<max_idx[0] && outer_idx[1][0]>=0) neighbours.emplace_back(outer_idx[0][1],outer_idx[1][0]);
401 if (outer_idx[0][1]<max_idx[0]) neighbours.emplace_back(outer_idx[0][1],idx[1]);
402 if (outer_idx[0][1]<max_idx[0] && outer_idx[1][1]<max_idx[1]) neighbours.emplace_back(outer_idx[0][1],outer_idx[1][1]);
403 if ( outer_idx[1][1]<max_idx[1]) neighbours.emplace_back(idx[0], outer_idx[1][1]);
404 if (outer_idx[0][0]>=0 && outer_idx[1][1]<max_idx[1]) neighbours.emplace_back(outer_idx[0][0],outer_idx[1][1]);
405 if (outer_idx[0][0]>=0 ) neighbours.emplace_back(outer_idx[0][0],idx[1]);
unsigned int AttributeType
bool isInsideMatrix(const std::array< PixelDiodeTree::IndexType, 2 > &idx) const
Return true if the given index describes a valid location inside the matrix.
bool empty() const
Return true if no sub-matrices are defined, indicates an invalid state.
std::array< CellIndexType, 2 > m_matrixDim
static constexpr bool validCellIndex(T cell_index)
Test whether the cell_index either row or column index could be valid The index may still be outside ...
bool isInsideMatrix(const Amg::Vector2D &local_position) const
Test whether the given local position is well within the matrix.
static void neighboursOfCell(const std::array< CellIndexType, 2 > &idx, const std::array< CellIndexType, 2 > &max_idx, std::vector< T_CellID > &neighbours)
Get indices of all adjacent cells.
std::tuple< IndexType, IndexType, IndexType > findFromT(const T &val, const std::vector< T > &split) const
helper template to find the final node in a quad tree.
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...
std::array< CellIndexType, 2 > computeIndex(PixelDiodeTree::IndexType sub_matrix_idx, PixelDiodeTree::IndexType diode_idx, const Vector2D &pos) const
Compute the 2D index (row, column) of a certain diode in a certain sub-matrix.
AttributeType attribute(IndexType idx) const
Get the attribute associated to a sub-matrix.
static constexpr IndexType s_invalid
void setAttribute(IndexType idx, AttributeType new_attribute)
Set the attribute associated to a sub-matrix.
std::vector< std::array< IndexType, 4 > > m_subMatrixIndex
std::array< Vector2D, 2 > m_matrixCorner
DiodeProxy diodeProxyFromIdx(const std::array< CellIndexType, 2 > &idx) const
find a diode by its 2D index (row, column) the returned proxy allows to compute the position and prov...
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...
Amg::Vector2D::Scalar FloatType
Vector2D findFromIdx(const std::array< CellIndexType, 2 > &idx) const
find a diode by its 2D index (row, column) and compute the position relative to the center of the ful...
unsigned int addDiode(const Vector2D &width, AttributeType attribute)
unsigned int cloneSingleSplitsToUnusedHalf()
Clone half with valid split indices to "unused" half with invalid split indices.
std::vector< AttributeType > m_attribute
Vector2D computePosition(PixelDiodeTree::IndexType sub_matrix_idx, PixelDiodeTree::IndexType diode_idx, const std::array< CellIndexType, 2 > &idx) const
Compute the position of a certain diode in a certain sub-matrix.
std::vector< Vector2D > m_posSplit
DiodeProxy diodeProxyFromPos(const Vector2D &pos) const
Find a diode by the position relative to the center of the full diode matrix.
static constexpr std::array< PixelDiodeTree::CellIndexType, 2 > makeCellIndex(T local_x_idx, T local_y_idx)
Create a 2D cell index from the indices in local-x (phi, row) and local-y (eta, column) direction.
PixelDiodeTree(const Vector2D &total_width)
std::vector< std::array< CellIndexType, 2 > > m_idxSplit
std::string debugStringRepr() const
Dump the diode tree structure into a string.
void computeMatrixCorner(const std::array< PixelDiodeTree::CellIndexType, 2 > &matrix_dim)
Compute the effective maximum lower and upper corner positions of the matrix.
void setDiodeForSubMatrix(unsigned int sub_matrix_idx, unsigned int split_i, unsigned int diode_idx)
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...
unsigned int split(const std::array< CellIndexType, 2 > &idx_split, const Vector2D &pos_split, AttributeType an_attribute, unsigned int parent_idx=std::numeric_limits< unsigned int >::max(), unsigned int split_i=0)
const Vector2D & totalWidth() const
Return the total width of the diode matrix.
Eigen::Matrix< double, 2, 1 > Vector2D
std::vector< Vector2D > m_width
std::vector< Vector2D > m_invWidth
unsigned int addDiode(const Vector2D &width, AttributeType attribute=AttributeType{})
std::vector< AttributeType > m_attribute
A diode proxy which caches the position of a diode.
double xPhiMax() const
for backward compatibility, return the position of the lower edge of the diode in local-y(phi,...
double xEtaMin() const
for backward compatibility, return the position of the lower edge of the diode in local-y(eta,...
double phiWidth() const
for backward compatibility, return the pitch of a diode in local-x(phi, row) direction
DiodeProxyWithPosition(const PixelDiodeTree *diodeTree, PixelDiodeTree::IndexType subMatrixIdx, PixelDiodeTree::IndexType diodeIdx, Vector2D &&position)
double xPhiMin() const
for backward compatibility, return the position of the lower edge of the diode in local-x(phi,...
const Vector2D & position() const
get the cached position of this diode
friend class PixelDiodeTree
double etaWidth() const
for backward compatibility, return the pitch of a diode in local-y(eta, column) direction
double xEtaMax() const
for backward compatibility, return the position of the upper edge of the diode in local-y(eta,...
Helper class to access parameters of a diode.
unsigned int diodeAttribute() const
get the attribute associated to this diode (to be interpreted)
std::array< PixelDiodeTree::CellIndexType, 2 > computeIndex(const Vector2D &pos) const
Compute the full 2D index (row, column) of the diode in the full diode matrix.
const PixelDiodeTree * m_diodeTree
PixelDiodeTree::IndexType m_diodeIdx
DiodeProxy(const PixelDiodeTree *diodeTree, PixelDiodeTree::IndexType subMatrixIdx, PixelDiodeTree::IndexType diodeIdx)
unsigned int subMatrixAttribute() const
get the attribute associated to the sub-matrix of this diode (to be interpreted)
bool isValid() const
return true if this proxy refers to a valide diode
PixelDiodeTree::Vector2D computePosition(const std::array< CellIndexType, 2 > &idx) const
Compute the position of the diode.
const PixelDiodeTree::Vector2D & invWidth() const
get the inverse of the width of this diode.
PixelDiodeTree::IndexType m_subMatrixIdx
const PixelDiodeTree::Vector2D & width() const
get the width stored for this diode.
friend class PixelDiodeTree