ATLAS Offline Software
Loading...
Searching...
No Matches
PixelModuleHelper.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4#ifndef INDET_PIXELMODULEHELPER_H
5#define INDET_PIXELMODULEHELPER_H
6
8#include <cassert>
9#include <array>
10#include <stdexcept>
11#include "ModuleKeyHelper.h"
12
13namespace InDet {
16 class PixelModuleHelper : public ModuleKeyHelper<unsigned int, // key type
17 12, // bits for rows
18 12, // bits for columns
19 4, // bits for chip
20 2 // bits for defect type
21 > {
22 public:
23
24 static constexpr std::array<unsigned short,2> N_COLS_PER_GROUP {
25 8, //8 columns per group for square pixels
26 4}; //4 columns per group for rectangular pixels
27
28 // mask with every bit set for all chips, columns, rows, but the mask index bits.
29 static constexpr unsigned int getPixelMask() { return MaskUtils::createMask<0,ROW_BITS+COL_BITS+CHIP_BITS>(); }
30 // mask with row and lowest 3 column bits set to zero i.e. 8 adjacent columns
32 // mask with row and lowest 2 column bits set to zero i.e. 4 adjacent columns
34 // mask with row and column bits set to zero.
36
37
39 {
40 const InDetDD::PixelModuleDesign *pixelModuleDesign = dynamic_cast<const InDetDD::PixelModuleDesign *>(&design);
41 if (pixelModuleDesign) {
42 m_sensorColumns = pixelModuleDesign->columns();
43 m_sensorRows = pixelModuleDesign->rows();
44 if (pixelModuleDesign->rowsPerCircuit()==400 /* @TODO find a better way to identify when to swap columns and rows*/ ) {
45 // the front-ends of ITk ring triplet modules are rotated differently
46 // wrt. the offline coordinate system compared to quads and
47 // barrel triplets. Once these modules are identified, the translation
48 // works in exactly the same way, but columns and rows need to be swapped,
50 m_columns = pixelModuleDesign->rows();
51 m_rows = pixelModuleDesign->columns();
52 m_columnsPerCircuit = pixelModuleDesign->rowsPerCircuit();
53 m_rowsPerCircuit = pixelModuleDesign->columnsPerCircuit();
54 m_circuitsPerColumn = pixelModuleDesign->numberOfCircuitsPerRow();
55 m_circuitsPerRow = pixelModuleDesign->numberOfCircuitsPerColumn();
56 m_columnPitch = pixelModuleDesign->phiPitch();
57 m_rowPitch = pixelModuleDesign->etaPitch();
58 }
59 else {
61 m_rows = pixelModuleDesign->rows();
62 m_columns = pixelModuleDesign->columns();
63 m_rowsPerCircuit = pixelModuleDesign->rowsPerCircuit();
64 m_columnsPerCircuit = pixelModuleDesign->columnsPerCircuit();
65 m_circuitsPerRow = pixelModuleDesign->numberOfCircuitsPerRow();
67 m_columnPitch = pixelModuleDesign->etaPitch();
68 m_rowPitch = pixelModuleDesign->phiPitch();
69 }
71 }
72 }
73 static constexpr unsigned int N_MASKS=3;
74 static constexpr unsigned int nMasks() { return N_MASKS; }
75 std::array<unsigned int, N_MASKS> masks() const {
76 return std::array<unsigned int,N_MASKS> {
80 };
81 }
82 operator bool () const { return m_columns>0; }
83
84 unsigned int columns() const { return m_columns; }
85 unsigned int rows() const { return m_rows; }
86 unsigned int columnsPerCircuit() const { return m_columnsPerCircuit; }
87 unsigned int rowsPerCircuit() const { return m_rowsPerCircuit; }
88 unsigned int circuitsPerColumn() const { return m_circuitsPerColumn; }
89 unsigned int circuitsPerRow() const { return m_circuitsPerRow; }
90
91 float columnPitch() const { return m_columnPitch; }
92 float rowPitch() const { return m_rowPitch; }
93
99 unsigned int hardwareCoordinates(unsigned int row, unsigned int column) const {
100 unsigned int chip =0;
102 unsigned int tmp=row;
103 row=column;
104 column=tmp;
105 }
106 if (circuitsPerColumn()>1) {
107 assert( circuitsPerColumn() == 2);
108 chip += (row/rowsPerCircuit()) * circuitsPerRow();
109 row = row % rowsPerCircuit();
110 if (chip>0) {
111 row = rowsPerCircuit() - row -1;
112 column = columns() - column -1;
113 }
114 }
115 if (circuitsPerRow()>1) {
116 chip += column/columnsPerCircuit();
117 column = column%columnsPerCircuit();
118 }
119 return makeKey(0u, chip, column, row);
120 }
121
125 std::pair<unsigned int,unsigned int> offlineCoordinates(unsigned int key) const {
126 unsigned int chip = getChip(key);
127 unsigned int column = getColumn(key);
128 unsigned int row = getRow(key);
129 // handle special values
130 // used for merging
131 if (row == getLimitRowMax()) {
132 row=rowsPerCircuit()-1;
133 }
134 if (row == rowsPerCircuit()) {
135 column+=1u;
136 row=0u;
137 }
138
139 column+= columnsPerCircuit() * (chip%circuitsPerRow());
140 if (chip>=circuitsPerRow()) {
141 column=columns() - column -1;
142 row=rowsPerCircuit() - row -1;
143 row+=rowsPerCircuit() * (chip/circuitsPerRow());
144 }
146 std::swap(column,row);
147 }
148 if (row>=nSensorRows() || column>=nSensorColumns()) {
149 throw std::runtime_error("Invvalid offline coordinates");
150 }
151 return std::make_pair(row,column);
152 }
153
156 unsigned int nCells() const {
157 return nSensorColumns() * nSensorRows();
158 }
159
161 unsigned int nSensorColumns() const {
162 return m_sensorColumns;
163 }
164
166 unsigned int nSensorRows() const {
167 return m_sensorRows;
168 }
169
171 unsigned int nElements(unsigned int mask_i) const {
172 switch (mask_i) {
173 case 1:
174 return nSensorColumns() * circuitsPerRow() / (m_rectangularPixels ? 4 : 8);
175 case 2:
177 default:
178 assert( mask_i==0);
179 return nCells();
180 }
181 }
182
187 std::array<unsigned int,4> offlineRange(const std::pair<unsigned int,unsigned int> &range) const {
188 if (range.first != range.second) {
189 // if (getRow(range.first) !=0) {
190 // throw std::runtime_error("invalid key");
191 // };
192
193 std::pair<unsigned int, unsigned int> start=offlineCoordinates(range.first);
194 std::pair<unsigned int, unsigned int> end=offlineCoordinates(range.second);
195 return std::array<unsigned int,4>{ std::min(start.first, end.first), std::max(start.first, end.first)+1,
196 std::min(start.second, end.second), std::max(start.second,end.second)+1};
197 }
198 else {
199 std::pair<unsigned int, unsigned int> start=offlineCoordinates(range.first);
200 return std::array<unsigned int,4>{ start.first, start.first+1,
201 start.second, start.second+1};
202 }
203 }
205
206 private:
207
208 unsigned short m_sensorRows=0;
209 unsigned short m_sensorColumns=0;
210 unsigned short m_rows = 0;
211 unsigned short m_columns = 0;
212 unsigned short m_rowsPerCircuit = 0;
213 unsigned short m_columnsPerCircuit = 0;
214 unsigned char m_circuitsPerRow = 0;
215 unsigned char m_circuitsPerColumn = 0;
216
217 float m_columnPitch = 0;
218 float m_rowPitch = 0;
219
222 };
223}
224#endif
Class used to describe the design of a module (diode segmentation and readout scheme)
int columns() const
Number of cell columns per module:
int rows() const
Number of cell rows per module:
int numberOfCircuitsPerRow() const
Number of circuits per row:
int rowsPerCircuit() const
Number of cell rows per circuit:
int numberOfCircuitsPerColumn() const
Number of circuits per column:
int columnsPerCircuit() const
Number of cell columns per circuit:
virtual double etaPitch() const
Pitch in eta direction.
virtual double phiPitch() const
Pitch in phi direction.
Base class for the detector design classes for Pixel and SCT.
static constexpr unsigned int getColGroup8Mask()
unsigned int circuitsPerColumn() const
std::pair< unsigned int, unsigned int > offlineCoordinates(unsigned int key) const
compute offline coordinates from "hardware" coordinates
unsigned int rows() const
static constexpr std::array< unsigned short, 2 > N_COLS_PER_GROUP
static constexpr unsigned int nMasks()
unsigned int columnsPerCircuit() const
unsigned int nSensorRows() const
Return the number of offline rows.
unsigned int nCells() const
Return total number of pixels per module.
unsigned int hardwareCoordinates(unsigned int row, unsigned int column) const
compute "hardware" coordinates from offline coordinates.
unsigned int rowsPerCircuit() const
static constexpr unsigned int getPixelMask()
PixelModuleHelper(const InDetDD::SiDetectorDesign &design)
std::array< unsigned int, 4 > offlineRange(const std::pair< unsigned int, unsigned int > &range) const
Function to return offline column and row ranges matching the defect-area of the given key (used for ...
unsigned int columns() const
static constexpr unsigned int getChipMask()
std::array< unsigned int, N_MASKS > masks() const
unsigned int nElements(unsigned int mask_i) const
return the maximum number of unique mask (or group) defects per module.
unsigned int circuitsPerRow() const
unsigned int nSensorColumns() const
Return the number of offline columns.
static constexpr unsigned int N_MASKS
static constexpr unsigned int getColGroup4Mask()
static consteval T createMask()
Convenience method to create a mask for which exactly one contiguous sequence of bits is set to 1.
Primary Vertex Finder.
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)
Helper class to create keys for defects described by chip, column and row indices,...
static constexpr unsigned int makeKey(bool is_range, unsigned int chip, unsigned int col, unsigned int row=0u)
static constexpr unsigned int getRow(unsigned int key)
static constexpr unsigned int getChip(unsigned int key)
static constexpr unsigned int getColumn(unsigned int key)