ATLAS Offline Software
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 
5 #include "PixelReadoutManager.h"
6 
11 
12 // #define PIXEL_DEBUG
13 
14 namespace 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!");
43  return PixelModuleType::NONE;
44  }
45 
47  if (m_idHelper->is_dbm(id)) {
48  return PixelModuleType::DBM;
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 
67  return PixelModuleType::NONE;
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!");
89  }
90 
92  if (p_design->numberOfCircuits() == 2) { // IBL planar
93  if (col == 0 || col == p_design->columnsPerCircuit() - 1) { // column edge =0,79
94  return PixelDiodeType::LONG;
95  }
97  }
99  }
100 
102  if (col > 0 && col < p_design->columnsPerCircuit() - 1) {
103  if (row >= p_design->rowsPerCircuit() / 2 - 1 - 6 - 1 && row <= p_design->rowsPerCircuit() / 2 - 1) {
104  if ((row - (p_design->rowsPerCircuit() / 2 - 1 - 6) + 1) % 2 + 1 == 1) {
105  return PixelDiodeType::LONG;
106  }
107  if ((row - (p_design->rowsPerCircuit() / 2 - 1 - 6) + 1) % 2 + 1 == 2) {
108  return PixelDiodeType::GANGED;
109  }
110  }
111  return PixelDiodeType::NORMAL;
112  }
113 
114  if (col == 0 || col==p_design->columnsPerCircuit() - 1) {
115  if (row >= p_design->rowsPerCircuit() / 2 - 1 - 6 - 1) {
116  return PixelDiodeType::GANGED;
117  }
118  return PixelDiodeType::LONG;
119  }
120 
121  ATH_MSG_WARNING("Pixel Type : the col number should be 0-" << p_design->columnsPerCircuit() << ", not " <<col);
122  return PixelDiodeType::NORMAL;
123  }
124 
125  return PixelDiodeType::NORMAL;
126 }
127 
128 
130  uint32_t FE,
131  uint32_t row,
132  uint32_t column) const
133 {
134  return getPixelId(m_idHelper->wafer_id(offlineIdHash), FE, row, column);
135 }
136 
137 
139  uint32_t FE,
140  uint32_t row,
141  uint32_t column) const
142 {
143  const SiDetectorElement *element = m_detManager->getDetectorElement(offlineId);
144  const PixelModuleDesign *p_design = static_cast<const PixelModuleDesign *>(&element->design());
146  ATH_MSG_ERROR("RD53 readout technologies not supported!");
147  return {};
148  }
149 
150  // Identify the module type
151  PixelModuleType moduleType = getModuleType(offlineId);
152  unsigned int columnsPerFE = p_design->columnsPerCircuit();
153  unsigned int FEsPerHalfModule = p_design->numberOfCircuits();
154  unsigned int rowsPerFE = 0;
155  int column_row_offset = 0;
157  rowsPerFE = p_design->rowsPerCircuit();
158  column_row_offset = -1;
159  if (moduleType == PixelModuleType::DBM) {
160  // DBM_Module defines rowsPerCircuit as number of hardware columns, and columnsPerFE as number of hardware rows.
161  // swap them to match hardware row, column in comparisons and computations
162  std::swap (columnsPerFE,rowsPerFE);
163  }
164  }
165  else if (p_design->getReadoutTechnology() == PixelReadoutTechnology::FEI3) {
166  rowsPerFE = p_design->rowsPerCircuit()/2+4; // normal + ganged
167  }
168 
169  // ---------------------
170  // Check input sanity
171  // ---------------------
172 
173  // Correct row, column
174  row = row + column_row_offset;
175  column = column + column_row_offset;
176 
177  if (row>=rowsPerFE || column>=columnsPerFE || FE>=((moduleType == PixelModuleType::IBL_PLANAR || moduleType == PixelModuleType::IBL_3D || moduleType == PixelModuleType::DBM) ? FEsPerHalfModule:2*FEsPerHalfModule)) {
178  ATH_MSG_DEBUG("Illegal pixel requested OfflineID: " << std::hex << offlineId << std::dec << " FE: " << FE << " row: " << row << " column: " << column);
179  ATH_MSG_DEBUG("Limits are: FE < " << ((moduleType == PixelModuleType::IBL_PLANAR || moduleType == PixelModuleType::IBL_3D || moduleType == PixelModuleType::DBM) ? FEsPerHalfModule : 2*FEsPerHalfModule) << ", row < " << rowsPerFE << ", column < " << columnsPerFE);
180  return {}; // illegal Identifier, standardized for PixelRodDecoder
181  }
182 
183  // ---------------------
184  // Convert row/column to eta/phi indices
185  // ---------------------
186  unsigned int phi_index, eta_index;
187  switch (moduleType)
188  {
190  eta_index = rowsPerFE-1-row;
191  if (m_idHelper->barrel_ec(offlineId)>0) { // A side (pos. eta)
192  phi_index = column;
193  }
194  else { // C side
195  phi_index = columnsPerFE-1-column;
196  }
197  break;
198 
200  phi_index = rowsPerFE-1-row;
201  eta_index = FE*columnsPerFE+column;
202  break;
203 
205  phi_index = rowsPerFE-1-row;
206  eta_index = FE*columnsPerFE+column;
207  break;
208 
209  default: // pixels
210  if (FE<FEsPerHalfModule) {
211  phi_index = ((2*rowsPerFE)-1)-row;
212  eta_index = ((columnsPerFE*FEsPerHalfModule)-1)-(column+(FE*columnsPerFE));
213  }
214  else {
215  phi_index = row;
216  eta_index = ((FE-FEsPerHalfModule)*columnsPerFE)+column;
217  }
218  if (moduleType == PixelModuleType::PIX_ENDCAP) {
219  // Swap phi_index for even endcap modules
220  if ((m_idHelper->phi_module(offlineId))%2==0) {
221  phi_index = 2*rowsPerFE-phi_index-1;
222  ATH_MSG_DEBUG("Even disk module found, phi module: " << m_idHelper->phi_module(offlineId) << " swapped phi index to : " << phi_index);
223  }
224  }
225  break;
226  }
227 
228  Identifier diodeId = m_idHelper->pixel_id(offlineId, phi_index, eta_index);
229 
230 #ifdef PIXEL_DEBUG
231  unsigned int eta_index_max = m_idHelper->eta_index_max(offlineId);
232  unsigned int phi_index_max = m_idHelper->phi_index_max(offlineId);
233  if (eta_index>eta_index_max) {
234  ATH_MSG_DEBUG("Error! eta_index: " << eta_index << " > eta_index_max: " << eta_index_max);
235  }
236  if (phi_index>phi_index_max) {
237  ATH_MSG_DEBUG("Error! phi_index: " << phi_index << " > phi_index_max: " << phi_index_max);
238  }
239  //consistency check - to be removed to speed up
240  uint32_t check_FE = getFE(diodeId, offlineId);
241  uint32_t check_row = getRow(diodeId, offlineId) + column_row_offset;
242  uint32_t check_column = getColumn(diodeId, offlineId) + column_row_offset;
243  if (check_FE!=FE || check_row!=row || check_column!=column) {
244  ATH_MSG_WARNING("identify OfflineID: 0x" << std::hex << offlineId << std::dec << " FE: " << FE << " row: " << row << " column: " << column << " unequal to:");
245  ATH_MSG_WARNING("identify PixelID: 0x" << std::hex << diodeId << std::dec << " FE: " << check_FE << " row: " << check_row << " column: " << check_column);
246  }
247 #endif
248 
249  return diodeId;
250 }
251 
252 
254  Identifier offlineId) const {
255 
256  const SiDetectorElement *element = m_detManager->getDetectorElement(offlineId);
257  return getFE(diodeId, offlineId, element);
258 }
259 
261  Identifier offlineId,
262  const SiDetectorElement* element) const
263 {
264  const PixelModuleDesign *p_design = static_cast<const PixelModuleDesign *>(&element->design());
266  ATH_MSG_ERROR("RD53 readout technologies not supported!");
267  return 0xffffffff;
268  }
269 
270  unsigned int columnsPerFE = p_design->columnsPerCircuit();
271  unsigned int FEsPerHalfModule = p_design->numberOfCircuits();
272  unsigned int rowsPerFE = 0;
274  rowsPerFE = p_design->rowsPerCircuit();
275  }
276  else if (p_design->getReadoutTechnology() == PixelReadoutTechnology::FEI3) {
277  rowsPerFE = p_design->rowsPerCircuit()/2+4; // normal + ganged
278  }
279 
280  // ---------------------
281  // Set module properties
282  // ---------------------
283  PixelModuleType moduleType = getModuleType(offlineId);
284  unsigned int FE;
285  unsigned int phi_index = m_idHelper->phi_index(diodeId);
286  int eta_index = m_idHelper->eta_index(diodeId);
287 
288  switch (moduleType)
289  {
291  FE = 0; // simple as that
292  return FE;
293  break;
294 
296  // Swap phi_index for even endcap modules
297  if ((m_idHelper->phi_module(offlineId))%2==0) {
298  phi_index = 2*rowsPerFE-phi_index-1;
299  }
300  break;
301 
302  default: // PIX_BARREL + IBL
303  break;
304  }
305 
306 
307  // ---------------------
308  // Compute FE number
309  // ---------------------
310  if (phi_index>=rowsPerFE) {
311  FE = (int)((FEsPerHalfModule-1)-(eta_index/columnsPerFE));
312  }
313  else {
314  FE = (int)(eta_index/columnsPerFE)+FEsPerHalfModule;
315  }
316 
317  // For IBL, the above returns FE number in range [2,3] (planar), or [1] (3D sensors).
318  // Change that to be [0,1] (planar) and [0] (3D) for consistency
319  if (moduleType == PixelModuleType::IBL_PLANAR || moduleType == PixelModuleType::IBL_3D) { FE = FE - FEsPerHalfModule; }
320 
321  return FE;
322 }
323 
324 
326  Identifier offlineId) const
327 {
328  const SiDetectorElement *element = m_detManager->getDetectorElement(offlineId);
329  const PixelModuleDesign *p_design = static_cast<const PixelModuleDesign *>(&element->design());
331  ATH_MSG_ERROR("RD53 readout technologies not supported!");
332  return 0xffffffff;
333  }
334 
335  unsigned int columnsPerFE = p_design->columnsPerCircuit();
336  unsigned int rowsPerFE = 0;
337  int column_offset = 0;
339  rowsPerFE = p_design->rowsPerCircuit();
340  column_offset = 1;
341  }
342  else if (p_design->getReadoutTechnology() == PixelReadoutTechnology::FEI3) {
343  rowsPerFE = p_design->rowsPerCircuit()/2+4; // normal + ganged
344  }
345 
346  PixelModuleType moduleType = getModuleType(offlineId);
347 
348  unsigned int phi_index = m_idHelper->phi_index(diodeId);
349  int eta_index = m_idHelper->eta_index(diodeId);
350 
351  // ---------------------
352  // Set module properties
353  // ---------------------
354  switch (moduleType)
355  {
357  break;
358 
360  // Swap phi_index for even endcap modules
361  if ((m_idHelper->phi_module(offlineId))%2==0) {
362  phi_index = 2*rowsPerFE-phi_index-1;
363  }
364  break;
365 
366  default: // PIX_BARREL + IBL
367  break;
368  }
369 
370  // ---------------------
371  // Convert eta index to column number
372  // ---------------------
373  int column{};
374  // DBM (column <-> phi_index)
375  if (moduleType == PixelModuleType::DBM) {
376  if (m_idHelper->barrel_ec(offlineId)>0) {
377  column = m_idHelper->phi_index(diodeId); // A side
378  }
379  else {
380  column = columnsPerFE-m_idHelper->phi_index(diodeId)-1; // C side
381  }
382  }
383  // Pixels, IBL
384  else {
385  if ((phi_index>=rowsPerFE)) {
386  column = (columnsPerFE-1)-(eta_index%columnsPerFE);
387  }
388  else {
389  column = eta_index%columnsPerFE;
390  }
391  }
392 
393  // ---------------------
394  // Check output sanity
395  // ---------------------
396  if (column >= (int)columnsPerFE) {
397  ATH_MSG_ERROR("Computed column number exceeds maximum value: col = " << column + column_offset << " (max = " << columnsPerFE << ")");
398  return 0xffffffff;
399  }
400 
401  return column + column_offset;
402 }
403 
404 
406  Identifier offlineId) const
407 {
408  const SiDetectorElement *element = m_detManager->getDetectorElement(offlineId);
409  const PixelModuleDesign *p_design = static_cast<const PixelModuleDesign *>(&element->design());
411  ATH_MSG_ERROR("RD53 readout technologies not supported!");
412  return 0xffffffff;
413  }
414 
415  unsigned int rowsPerFE = 0;
416  int row_offset = 0;
418  rowsPerFE = p_design->rowsPerCircuit();
419  row_offset = 1;
420  }
421  else if (p_design->getReadoutTechnology() == PixelReadoutTechnology::FEI3) {
422  rowsPerFE = p_design->rowsPerCircuit()/2+4; // normal + ganged
423  }
424 
425  PixelModuleType moduleType = getModuleType(offlineId);
426 
427  unsigned int phi_index = m_idHelper->phi_index(diodeId);
428 
429  // ---------------------
430  // Set module properties
431  // ---------------------
432  switch (moduleType)
433  {
435  break;
436 
438  // Swap phi_index for even endcap modules
439  if ((m_idHelper->phi_module(offlineId))%2==0) {
440  phi_index = 2*rowsPerFE-phi_index-1;
441  }
442  break;
443 
444  default: // PIX_BARREL + IBL
445  break;
446  }
447 
448  // ---------------------
449  // Convert phi index to row number
450  // ---------------------
451  int row{};
452  switch (moduleType)
453  {
455  // Row <-> eta_index
456  row = rowsPerFE-m_idHelper->eta_index(diodeId)-1;
457  break;
458 
460  row = rowsPerFE-1-phi_index;
461  break;
462 
464  row = rowsPerFE-1-phi_index;
465  break;
466 
467  default: // Pixels
468  if (phi_index>=rowsPerFE) {
469  row = ((2*rowsPerFE)-1)-phi_index;
470  }
471  else {
472  row = phi_index;
473  }
474  break;
475  }
476 
477  // ---------------------
478  // Check output sanity
479  // ---------------------
480  if (row >= (int)rowsPerFE) {
481  ATH_MSG_ERROR("Computed row number exceeds maximum value: row = " << row + row_offset << "(max = " << rowsPerFE << ")");
482  return 0xffffffff;
483  }
484  return row + row_offset;
485 }
486 
487 } // namespace InDetDD
PixelID.h
This is an Identifier helper class for the Pixel subdetector. This class is a factory for creating co...
PixelID::phi_index
int phi_index(const Identifier &id) const
Definition: PixelID.h:654
InDetDD::PixelReadoutManager::m_detStore
ServiceHandle< StoreGateSvc > m_detStore
Definition: PixelReadoutManager.h:54
InDetDD::PixelModuleDesign
Definition: PixelModuleDesign.h:45
InDetDD::PixelModuleType::DBM
@ DBM
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
InDetDD::PixelReadoutManager::getPixelId
virtual Identifier getPixelId(Identifier offlineId, uint32_t FE, uint32_t row, uint32_t column) const override final
Definition: PixelReadoutManager.cxx:138
PixelID::barrel_ec
int barrel_ec(const Identifier &id) const
Values of different levels (failure returns 0)
Definition: PixelID.h:615
InDetDD::PixelDiodeType
PixelDiodeType
Definition: PixelReadoutDefinitions.h:28
DeMoUpdate.column
dictionary column
Definition: DeMoUpdate.py:1110
InDetDD::PixelReadoutTechnology::FEI3
@ FEI3
keylayer_zslicemap.row
row
Definition: keylayer_zslicemap.py:155
InDetDD::PixelDiodeType::GANGED
@ GANGED
PixelID::wafer_id
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module) const
For a single crystal.
Definition: PixelID.h:360
InDetDD::PixelReadoutTechnology::RD53
@ RD53
PixelReadoutManager.h
InDetDD::PixelModuleType::NONE
@ NONE
PixelDetectorManager.h
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
InDetDD::PixelDiodeType::LONG
@ LONG
PixelID::phi_index_max
int phi_index_max(const Identifier &id) const
Definition: PixelID.cxx:143
PixelID::eta_index_max
int eta_index_max(const Identifier &id) const
Definition: PixelID.cxx:162
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
InDetDD::PixelModuleDesign::numberOfCircuits
int numberOfCircuits() const
Total number of circuits:
Definition: PixelModuleDesign.h:306
PixelID::eta_index
int eta_index(const Identifier &id) const
Definition: PixelID.h:660
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
InDetDD::PixelModuleType
PixelModuleType
Definition: PixelReadoutDefinitions.h:18
Handler::svc
AthROOTErrorHandlerSvc * svc
Definition: AthROOTErrorHandlerSvc.cxx:10
createCablingJSON.eta_index
int eta_index
Definition: createCablingJSON.py:14
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
InDetDD::PixelReadoutManager::PixelReadoutManager
PixelReadoutManager(const std::string &name, ISvcLocator *svc)
Definition: PixelReadoutManager.cxx:17
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:239
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
InDetDD::PixelReadoutManager::getFE
virtual uint32_t getFE(Identifier diodeId, Identifier offlineId) const override final
Definition: PixelReadoutManager.cxx:253
InDetDD::PixelReadoutManager::getRow
virtual uint32_t getRow(Identifier diodeId, Identifier offlineId) const override final
Definition: PixelReadoutManager.cxx:405
InDetDD::SiDetectorElement
Definition: SiDetectorElement.h:109
InDetDD::PixelReadoutTechnology::FEI4
@ FEI4
InDetDD::PixelModuleDesign::getReadoutTechnology
PixelReadoutTechnology getReadoutTechnology() const
Definition: PixelModuleDesign.h:391
InDetDD::PixelModuleType::IBL_PLANAR
@ IBL_PLANAR
SiDetectorElement.h
PixelID::is_dbm
bool is_dbm(const Identifier &id) const
Test for dbm - WARNING: id MUST be pixel id, otherwise answer is not accurate. Use SiliconID for gene...
Definition: PixelID.h:608
InDetDD::PixelReadoutManager::getPixelIdfromHash
virtual Identifier getPixelIdfromHash(IdentifierHash offlineIdHash, uint32_t FE, uint32_t row, uint32_t column) const override final
Definition: PixelReadoutManager.cxx:129
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
InDetDD::PixelModuleType::PIX_ENDCAP
@ PIX_ENDCAP
InDetDD::PixelModuleDesign::rowsPerCircuit
int rowsPerCircuit() const
Number of cell rows per circuit:
Definition: PixelModuleDesign.h:326
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
InDetDD
Message Stream Member.
Definition: FakeTrackBuilder.h:8
PixelModuleDesign.h
InDetDD::PixelReadoutManager::getColumn
virtual uint32_t getColumn(Identifier diodeId, Identifier offlineId) const override final
Definition: PixelReadoutManager.cxx:325
InDetDD::PixelReadoutManager::m_detManager
const PixelDetectorManager * m_detManager
Definition: PixelReadoutManager.h:55
InDetDD::PixelReadoutManager::m_idHelper
const PixelID * m_idHelper
Definition: PixelReadoutManager.h:56
PixelID::pixel_id
Identifier pixel_id(int barrel_ec, int layer_disk, int phi_module, int eta_module, int phi_index, int eta_index) const
For an individual pixel.
Definition: PixelID.h:428
InDetDD::PixelReadoutManager::getModuleType
virtual PixelModuleType getModuleType(Identifier id) const override final
Definition: PixelReadoutManager.cxx:36
InDetDD::PixelDetectorManager::getDetectorElement
virtual const SiDetectorElement * getDetectorElement(const Identifier &id) const override
access to individual elements : via Identifier
Definition: PixelDetectorManager.cxx:80
InDetDD::PixelDiodeType::NORMAL
@ NORMAL
InDetDD::PixelReadoutManager::getDiodeType
virtual PixelDiodeType getDiodeType(Identifier id) const override final
Definition: PixelReadoutManager.cxx:70
IdentifierHash
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
Definition: IdentifierHash.h:25
InDetDD::PixelModuleType::PIX_BARREL
@ PIX_BARREL
InDetDD::SiDetectorElement::design
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
PixelID::phi_module
int phi_module(const Identifier &id) const
Definition: PixelID.h:640
InDetDD::PixelModuleType::IBL_3D
@ IBL_3D
InDetDD::PixelModuleDesign::columnsPerCircuit
int columnsPerCircuit() const
Number of cell columns per circuit:
Definition: PixelModuleDesign.h:321
InDetDD::PixelReadoutManager::initialize
virtual StatusCode initialize() override final
Definition: PixelReadoutManager.cxx:24
Identifier
Definition: IdentifierFieldParser.cxx:14