ATLAS Offline Software
Loading...
Searching...
No Matches
PixelReadoutManager.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
11
12// #define PIXEL_DEBUG
13
14namespace InDetDD
15{
16
18 ISvcLocator *svc)
19 : base_class(name, svc)
20{
21}
22
23
25{
26 ATH_MSG_DEBUG("PixelReadoutManager::initialize()");
27
28 ATH_CHECK(m_detStore.retrieve());
29 ATH_CHECK(m_detStore->retrieve(m_detManager, "Pixel"));
30 ATH_CHECK(m_detStore->retrieve(m_idHelper, "PixelID"));
31
32 return StatusCode::SUCCESS;
33}
34
35
37{
38 const Identifier wafer_id = m_idHelper->wafer_id(id);
39 const SiDetectorElement *element = m_detManager->getDetectorElement(wafer_id);
40 const PixelModuleDesign *p_design = static_cast<const PixelModuleDesign *>(&element->design());
42 ATH_MSG_ERROR("RD53 readout technologies not supported!");
44 }
45
47 if (m_idHelper->is_dbm(id)) {
49 }
50
51 if (p_design->numberOfCircuits() == 2) {
53 }
54
56 }
57
59 if (std::abs(m_idHelper->barrel_ec(id)) == 0) {
61 }
62 if (std::abs(m_idHelper->barrel_ec(id)) == 2) {
64 }
65 }
66
68}
69
71
72 const Identifier wafer_id = m_idHelper->wafer_id(id);
73 const SiDetectorElement *element = m_detManager->getDetectorElement(wafer_id);
74 return getDiodeType(id,element);
75}
76
78 const SiDetectorElement* element) const
79{
80 Identifier diodeId = id;
81 Identifier offlineId = m_idHelper->wafer_id(diodeId);
82 int col = getColumn(diodeId, offlineId);
83 int row = getRow(diodeId, offlineId);
84
85 const PixelModuleDesign *p_design = static_cast<const PixelModuleDesign *>(&element->design());
87 ATH_MSG_ERROR("RD53 readout technologies not supported!");
88 }
89 else if (p_design->getReadoutTechnology() == PixelReadoutTechnology::FEI4) {
90 if (p_design->numberOfCircuits() == 2) { // IBL planar
91 // col for FEI4 is in [1-80] not [0-79]
92 if (col == 0+1 || col == p_design->columnsPerCircuit() - 1+1) { // column edge =1,80
94 }
95 }
96 }
97 else if (p_design->getReadoutTechnology() == PixelReadoutTechnology::FEI3) {
98 const unsigned int rows_per_front_end = p_design->rowsPerCircuit()/2;
99 assert(static_cast<unsigned int>(row) < rows_per_front_end+4);
100 assert(col < p_design->columnsPerCircuit());
101 // the last 4 pixels of the half_matrix (160-163) and the odd rows of the
102 // last 6 rows of the circuit (153-159) are ganged.
103 if ( static_cast<unsigned int>(row)>=rows_per_front_end
104 || (static_cast<unsigned int>(row)>=rows_per_front_end - 1-6 && (row&1) ==1)) {
106 }
107 // the pixels of the first or last column are long if they are not ganged
108 if (col==0 || col ==p_design->columnsPerCircuit()-1) {
110 }
111 }
112
114}
115
116
118 uint32_t FE,
119 uint32_t row,
120 uint32_t column) const
121{
122 return getPixelId(m_idHelper->wafer_id(offlineIdHash), FE, row, column);
123}
124
125
127 uint32_t FE,
128 uint32_t row,
129 uint32_t column) const
130{
131 const SiDetectorElement *element = m_detManager->getDetectorElement(offlineId);
132 const PixelModuleDesign *p_design = static_cast<const PixelModuleDesign *>(&element->design());
134 ATH_MSG_ERROR("RD53 readout technologies not supported!");
135 return {};
136 }
137
138 // Identify the module type
139 PixelModuleType moduleType = getModuleType(offlineId);
140 unsigned int columnsPerFE = p_design->columnsPerCircuit();
141 unsigned int FEsPerHalfModule = p_design->numberOfCircuits();
142 unsigned int rowsPerFE = 0;
143 int column_row_offset = 0;
145 rowsPerFE = p_design->rowsPerCircuit();
146 column_row_offset = -1;
147 if (moduleType == PixelModuleType::DBM) {
148 // DBM_Module defines rowsPerCircuit as number of hardware columns, and columnsPerFE as number of hardware rows.
149 // swap them to match hardware row, column in comparisons and computations
150 std::swap (columnsPerFE,rowsPerFE);
151 }
152 }
153 else if (p_design->getReadoutTechnology() == PixelReadoutTechnology::FEI3) {
154 rowsPerFE = p_design->rowsPerCircuit()/2+4; // normal + ganged
155 }
156
157 // ---------------------
158 // Check input sanity
159 // ---------------------
160
161 // Correct row, column
162 row = row + column_row_offset;
163 column = column + column_row_offset;
164
165 if (row>=rowsPerFE || column>=columnsPerFE || FE>=((moduleType == PixelModuleType::IBL_PLANAR || moduleType == PixelModuleType::IBL_3D || moduleType == PixelModuleType::DBM) ? FEsPerHalfModule:2*FEsPerHalfModule)) {
166 ATH_MSG_DEBUG("Illegal pixel requested OfflineID: " << std::hex << offlineId << std::dec << " FE: " << FE << " row: " << row << " column: " << column);
167 ATH_MSG_DEBUG("Limits are: FE < " << ((moduleType == PixelModuleType::IBL_PLANAR || moduleType == PixelModuleType::IBL_3D || moduleType == PixelModuleType::DBM) ? FEsPerHalfModule : 2*FEsPerHalfModule) << ", row < " << rowsPerFE << ", column < " << columnsPerFE);
168 return {}; // illegal Identifier, standardized for PixelRodDecoder
169 }
170
171 // ---------------------
172 // Convert row/column to eta/phi indices
173 // ---------------------
174 unsigned int phi_index, eta_index;
175 switch (moduleType)
176 {
178 eta_index = rowsPerFE-1-row;
179 if (m_idHelper->barrel_ec(offlineId)>0) { // A side (pos. eta)
180 phi_index = column;
181 }
182 else { // C side
183 phi_index = columnsPerFE-1-column;
184 }
185 break;
186
188 phi_index = rowsPerFE-1-row;
189 eta_index = FE*columnsPerFE+column;
190 break;
191
193 phi_index = rowsPerFE-1-row;
194 eta_index = FE*columnsPerFE+column;
195 break;
196
197 default: // pixels
198 if (FE<FEsPerHalfModule) {
199 phi_index = ((2*rowsPerFE)-1)-row;
200 eta_index = ((columnsPerFE*FEsPerHalfModule)-1)-(column+(FE*columnsPerFE));
201 }
202 else {
203 phi_index = row;
204 eta_index = ((FE-FEsPerHalfModule)*columnsPerFE)+column;
205 }
206 if (moduleType == PixelModuleType::PIX_ENDCAP) {
207 // Swap phi_index for even endcap modules
208 if ((m_idHelper->phi_module(offlineId))%2==0) {
209 phi_index = 2*rowsPerFE-phi_index-1;
210 ATH_MSG_DEBUG("Even disk module found, phi module: " << m_idHelper->phi_module(offlineId) << " swapped phi index to : " << phi_index);
211 }
212 }
213 break;
214 }
215
216 Identifier diodeId = m_idHelper->pixel_id(offlineId, phi_index, eta_index);
217
218#ifdef PIXEL_DEBUG
219 unsigned int eta_index_max = m_idHelper->eta_index_max(offlineId);
220 unsigned int phi_index_max = m_idHelper->phi_index_max(offlineId);
221 if (eta_index>eta_index_max) {
222 ATH_MSG_DEBUG("Error! eta_index: " << eta_index << " > eta_index_max: " << eta_index_max);
223 }
224 if (phi_index>phi_index_max) {
225 ATH_MSG_DEBUG("Error! phi_index: " << phi_index << " > phi_index_max: " << phi_index_max);
226 }
227 //consistency check - to be removed to speed up
228 uint32_t check_FE = getFE(diodeId, offlineId);
229 uint32_t check_row = getRow(diodeId, offlineId) + column_row_offset;
230 uint32_t check_column = getColumn(diodeId, offlineId) + column_row_offset;
231 if (check_FE!=FE || check_row!=row || check_column!=column) {
232 ATH_MSG_WARNING("identify OfflineID: 0x" << std::hex << offlineId << std::dec << " FE: " << FE << " row: " << row << " column: " << column << " unequal to:");
233 ATH_MSG_WARNING("identify PixelID: 0x" << std::hex << diodeId << std::dec << " FE: " << check_FE << " row: " << check_row << " column: " << check_column);
234 }
235#endif
236
237 return diodeId;
238}
239
240
242 Identifier offlineId) const {
243
244 const SiDetectorElement *element = m_detManager->getDetectorElement(offlineId);
245 return getFE(diodeId, offlineId, element);
246}
247
249 Identifier offlineId,
250 const SiDetectorElement* element) const
251{
252 const PixelModuleDesign *p_design = static_cast<const PixelModuleDesign *>(&element->design());
254 ATH_MSG_ERROR("RD53 readout technologies not supported!");
255 return 0xffffffff;
256 }
257
258 unsigned int columnsPerFE = p_design->columnsPerCircuit();
259 unsigned int FEsPerHalfModule = p_design->numberOfCircuits();
260 unsigned int rowsPerFE = 0;
262 rowsPerFE = p_design->rowsPerCircuit();
263 }
264 else if (p_design->getReadoutTechnology() == PixelReadoutTechnology::FEI3) {
265 rowsPerFE = p_design->rowsPerCircuit()/2+4; // normal + ganged
266 }
267
268 // ---------------------
269 // Set module properties
270 // ---------------------
271 PixelModuleType moduleType = getModuleType(offlineId);
272 unsigned int FE;
273 unsigned int phi_index = m_idHelper->phi_index(diodeId);
274 int eta_index = m_idHelper->eta_index(diodeId);
275
276 switch (moduleType)
277 {
279 FE = 0; // simple as that
280 return FE;
281 break;
282
284 // Swap phi_index for even endcap modules
285 if ((m_idHelper->phi_module(offlineId))%2==0) {
286 phi_index = 2*rowsPerFE-phi_index-1;
287 }
288 break;
289
290 default: // PIX_BARREL + IBL
291 break;
292 }
293
294
295 // ---------------------
296 // Compute FE number
297 // ---------------------
298 if (phi_index>=rowsPerFE) {
299 FE = (int)((FEsPerHalfModule-1)-(eta_index/columnsPerFE));
300 }
301 else {
302 FE = (int)(eta_index/columnsPerFE)+FEsPerHalfModule;
303 }
304
305 // For IBL, the above returns FE number in range [2,3] (planar), or [1] (3D sensors).
306 // Change that to be [0,1] (planar) and [0] (3D) for consistency
307 if (moduleType == PixelModuleType::IBL_PLANAR || moduleType == PixelModuleType::IBL_3D) { FE = FE - FEsPerHalfModule; }
308
309 return FE;
310}
311
312
314 Identifier offlineId) const
315{
316 const SiDetectorElement *element = m_detManager->getDetectorElement(offlineId);
317 const PixelModuleDesign *p_design = static_cast<const PixelModuleDesign *>(&element->design());
319 ATH_MSG_ERROR("RD53 readout technologies not supported!");
320 return 0xffffffff;
321 }
322
323 unsigned int columnsPerFE = p_design->columnsPerCircuit();
324 unsigned int rowsPerFE = 0;
325 int column_offset = 0;
327 rowsPerFE = p_design->rowsPerCircuit();
328 column_offset = 1;
329 }
330 else if (p_design->getReadoutTechnology() == PixelReadoutTechnology::FEI3) {
331 rowsPerFE = p_design->rowsPerCircuit()/2+4; // normal + ganged
332 }
333
334 PixelModuleType moduleType = getModuleType(offlineId);
335
336 unsigned int phi_index = m_idHelper->phi_index(diodeId);
337 int eta_index = m_idHelper->eta_index(diodeId);
338
339 // ---------------------
340 // Set module properties
341 // ---------------------
342 switch (moduleType)
343 {
345 break;
346
348 // Swap phi_index for even endcap modules
349 if ((m_idHelper->phi_module(offlineId))%2==0) {
350 phi_index = 2*rowsPerFE-phi_index-1;
351 }
352 break;
353
354 default: // PIX_BARREL + IBL
355 break;
356 }
357
358 // ---------------------
359 // Convert eta index to column number
360 // ---------------------
361 int column{};
362 // DBM (column <-> phi_index)
363 if (moduleType == PixelModuleType::DBM) {
364 if (m_idHelper->barrel_ec(offlineId)>0) {
365 column = m_idHelper->phi_index(diodeId); // A side
366 }
367 else {
368 column = columnsPerFE-m_idHelper->phi_index(diodeId)-1; // C side
369 }
370 }
371 // Pixels, IBL
372 else {
373 if ((phi_index>=rowsPerFE)) {
374 column = (columnsPerFE-1)-(eta_index%columnsPerFE);
375 }
376 else {
377 column = eta_index%columnsPerFE;
378 }
379 }
380
381 // ---------------------
382 // Check output sanity
383 // ---------------------
384 if (column >= (int)columnsPerFE) {
385 ATH_MSG_ERROR("Computed column number exceeds maximum value: col = " << column + column_offset << " (max = " << columnsPerFE << ")");
386 return 0xffffffff;
387 }
388
389 return column + column_offset;
390}
391
392
394 Identifier offlineId) const
395{
396 const SiDetectorElement *element = m_detManager->getDetectorElement(offlineId);
397 const PixelModuleDesign *p_design = static_cast<const PixelModuleDesign *>(&element->design());
399 ATH_MSG_ERROR("RD53 readout technologies not supported!");
400 return 0xffffffff;
401 }
402
403 unsigned int rowsPerFE = 0;
404 int row_offset = 0;
406 rowsPerFE = p_design->rowsPerCircuit();
407 row_offset = 1;
408 }
409 else if (p_design->getReadoutTechnology() == PixelReadoutTechnology::FEI3) {
410 rowsPerFE = p_design->rowsPerCircuit()/2+4; // normal + ganged
411 }
412
413 PixelModuleType moduleType = getModuleType(offlineId);
414
415 unsigned int phi_index = m_idHelper->phi_index(diodeId);
416
417 // ---------------------
418 // Set module properties
419 // ---------------------
420 switch (moduleType)
421 {
423 break;
424
426 // Swap phi_index for even endcap modules
427 if ((m_idHelper->phi_module(offlineId))%2==0) {
428 phi_index = 2*rowsPerFE-phi_index-1;
429 }
430 break;
431
432 default: // PIX_BARREL + IBL
433 break;
434 }
435
436 // ---------------------
437 // Convert phi index to row number
438 // ---------------------
439 int row{};
440 switch (moduleType)
441 {
443 // Row <-> eta_index
444 row = rowsPerFE-m_idHelper->eta_index(diodeId)-1;
445 break;
446
448 row = rowsPerFE-1-phi_index;
449 break;
450
452 row = rowsPerFE-1-phi_index;
453 break;
454
455 default: // Pixels
456 if (phi_index>=rowsPerFE) {
457 row = ((2*rowsPerFE)-1)-phi_index;
458 }
459 else {
460 row = phi_index;
461 }
462 break;
463 }
464
465 // ---------------------
466 // Check output sanity
467 // ---------------------
468 if (row >= (int)rowsPerFE) {
469 ATH_MSG_ERROR("Computed row number exceeds maximum value: row = " << row + row_offset << "(max = " << rowsPerFE << ")");
470 return 0xffffffff;
471 }
472 return row + row_offset;
473}
474
475} // namespace InDetDD
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
This is an Identifier helper class for the Pixel subdetector.
This is a "hash" representation of an Identifier.
Class used to describe the design of a module (diode segmentation and readout scheme)
PixelReadoutTechnology getReadoutTechnology() const
int rowsPerCircuit() const
Number of cell rows per circuit:
int numberOfCircuits() const
Total number of circuits:
int columnsPerCircuit() const
Number of cell columns per circuit:
virtual StatusCode initialize() override final
virtual Identifier getPixelId(Identifier offlineId, uint32_t FE, uint32_t row, uint32_t column) const override final
PixelReadoutManager(const std::string &name, ISvcLocator *svc)
const PixelDetectorManager * m_detManager
ServiceHandle< StoreGateSvc > m_detStore
virtual uint32_t getFE(Identifier diodeId, Identifier offlineId) const override final
virtual PixelModuleType getModuleType(Identifier id) const override final
virtual uint32_t getRow(Identifier diodeId, Identifier offlineId) const override final
virtual PixelDiodeType getDiodeType(Identifier id) const override final
virtual Identifier getPixelIdfromHash(IdentifierHash offlineIdHash, uint32_t FE, uint32_t row, uint32_t column) const override final
virtual uint32_t getColumn(Identifier diodeId, Identifier offlineId) const override final
Class to hold geometrical description of a silicon detector element.
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
Message Stream Member.
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)