ATLAS Offline Software
PixelGmxInterface.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
15 
19 #include <GeoModelRead/ReadGeoModel.h>
20 #include <GeoModelKernel/GeoFullPhysVol.h>
21 
22 namespace
23 {
24 constexpr int PixelHitIndex{0};
25 }
26 
27 
28 namespace InDetDD
29 {
30 
31 namespace ITk
32 {
33 
35  SiCommonItems *commonItems,
36  WaferTree *moduleTree)
37  : AthMessaging("PixelGmxInterface"),
38  m_detectorManager(detectorManager),
39  m_commonItems(commonItems),
40  m_moduleTree(moduleTree)
41 {}
42 
43 
44 int PixelGmxInterface::sensorId(std::map<std::string, int> &index) const
45 {
46  // Return the Simulation HitID (nothing to do with "ATLAS Identifiers" aka "Offline Identifiers")
47 
48  // Check if identifier is valid
49  // TODO: drop this check in the future
50  const PixelID *pixelIdHelper = dynamic_cast<const PixelID *>(m_commonItems->getIdHelper());
51  if (not pixelIdHelper){
52  ATH_MSG_ERROR("Failed dynamic_cast to PixelID in PixelGmxInterface::sensorId");
53  return -1;
54  }
55  Identifier id = pixelIdHelper->wafer_id(index["barrel_endcap"],
56  index["layer_wheel"],
57  index["phi_module"],
58  index["eta_module"]);
59  IdentifierHash hashId = pixelIdHelper->wafer_hash(id);
60  if (!hashId.is_valid()) {
61  ATH_MSG_WARNING("Invalid hash for Index list: " << index["barrel_endcap"] << " " << index["layer_wheel"] << " "
62  << index["eta_module"] << " " << index["phi_module"] << " " << index["side"]);
63  return -1;
64  }
65 
66  // Compute the actuall SiHitId
67  int hitIdOfModule = SiHitIdHelper::GetHelper()->buildHitId(PixelHitIndex,
68  index["barrel_endcap"],
69  index["layer_wheel"],
70  index["eta_module"],
71  index["phi_module"],
72  index["side"]);
73 
74  ATH_MSG_DEBUG("Index list: " << index["barrel_endcap"] << " " << index["layer_wheel"] << " "
75  << index["eta_module"] << " " << index["phi_module"] << " " << index["side"]);
76  ATH_MSG_DEBUG("hitIdOfModule = " << std::hex << hitIdOfModule << std::dec);
77  ATH_MSG_DEBUG(" bec = " << SiHitIdHelper::GetHelper()->getBarrelEndcap(hitIdOfModule)
78  << " lay = " << SiHitIdHelper::GetHelper()->getLayerDisk(hitIdOfModule)
79  << " eta = " << SiHitIdHelper::GetHelper()->getEtaModule(hitIdOfModule)
80  << " phi = " << SiHitIdHelper::GetHelper()->getPhiModule(hitIdOfModule)
81  << " side = " << SiHitIdHelper::GetHelper()->getSide(hitIdOfModule));
82 
83  return hitIdOfModule;
84 }
85 
86 
87 void PixelGmxInterface::addSensorType(const std::string& clas,
88  const std::string& typeName,
89  const std::map<std::string, std::string>& parameters)
90 {
91  ATH_MSG_DEBUG("addSensorType called for class " << clas << ", typeName " << typeName);
92 
93  if (clas == "SingleChip_RD53" || clas == "QuadChip_RD53") {
95  } else {
96  ATH_MSG_ERROR("addSensorType: unrecognised module class: " << clas);
97  ATH_MSG_ERROR("No module design created");
98  }
99 }
100 
101 
103  const std::map<std::string, std::string> &parameters)
104 {
105  int circuitsPerEta{2}; // row
106  int circuitsPerPhi{2}; // column
107  double thickness{0.150};
108  double pitchEta{};
109  double pitchPhi{};
110  double pitchEtaLong{};
111  double pitchPhiLong{};
112  double pitchEtaEnd{};
113  double pitchPhiEnd{};
114  int nEtaLongPerSide{};
115  int nPhiLongPerSide{};
116  int nEtaEndPerSide{};
117  int nPhiEndPerSide{};
118  int rowsPerChip{};
119  int columnsPerChip{};
120 
121  // unused
123  int readoutSide{1};
124  bool is3D{false};
125 
126  // read parameters
127  getParameter(typeName, parameters, "circuitsPerEta", circuitsPerEta);
128  getParameter(typeName, parameters, "circuitsPerPhi", circuitsPerPhi);
129  getParameter(typeName, parameters, "thickness", thickness);
130  getParameter(typeName, parameters, "is3D", is3D);
131  getParameter(typeName, parameters, "rows", rowsPerChip);
132  getParameter(typeName, parameters, "columns", columnsPerChip);
133  getParameter(typeName, parameters, "pitchEta", pitchEta);
134  getParameter(typeName, parameters, "pitchPhi", pitchPhi);
135  getParameter(typeName, parameters, "pitchEtaLong", pitchEtaLong);
136  getParameter(typeName, parameters, "pitchPhiLong", pitchPhiLong);
137  getParameter(typeName, parameters, "pitchEtaEnd", pitchEtaEnd);
138  getParameter(typeName, parameters, "pitchPhiEnd", pitchPhiEnd);
139  getParameter(typeName, parameters, "nPhiLongPerSide", nPhiLongPerSide);
140  getParameter(typeName, parameters, "nEtaLongPerSide", nEtaLongPerSide);
141  getParameter(typeName, parameters, "nPhiEndPerSide", nPhiEndPerSide);
142  getParameter(typeName, parameters, "nEtaEndPerSide", nEtaEndPerSide);
143 
144  //
145  // Make Module Design and add to DetectorManager
146  //
147  std::shared_ptr<const PixelDiodeMatrix> fullMatrix = buildMatrix(pitchPhi, pitchEta,
148  pitchPhiLong, pitchPhiEnd,
149  pitchEtaLong, pitchEtaEnd,
150  nPhiLongPerSide, nPhiEndPerSide,
151  nEtaLongPerSide, nEtaEndPerSide,
152  circuitsPerPhi, circuitsPerEta,
153  columnsPerChip, rowsPerChip);
154 
155  ATH_MSG_DEBUG("fullMatrix = buildMatrix(" << pitchPhi << ", " << pitchEta << ", "
156  << pitchPhiLong << ", " << pitchPhiEnd << ", "
157  << pitchEtaLong << ", " << pitchEtaEnd << ", "
158  << nPhiLongPerSide << ", " << nPhiEndPerSide << ", "
159  << nEtaLongPerSide << ", " << nEtaEndPerSide << ", "
160  << circuitsPerPhi << ", " << circuitsPerEta << ", "
161  << columnsPerChip << ", " << rowsPerChip << ")");
162  ATH_MSG_DEBUG("readout geo - design " << thickness << " "
163  << circuitsPerPhi << " " << circuitsPerEta << " "
164  << columnsPerChip << " " << rowsPerChip << " "
165  << columnsPerChip << " " << rowsPerChip << " "
166  << carrier << " " << readoutSide);
167 
168  //For optionally setting PixelBarrel,PixelEndcap,PixelInclined
169  //(so far) primarily useful for the latter to avoid orientation warnings
170  InDetDD::DetectorType detectorType{InDetDD::PixelBarrel}; // TODO: we should probably fail and not default to barrel here.
171  int detectorTypeEnum = 0;
172  if (checkParameter(typeName, parameters, "detectorType", detectorTypeEnum)) {
173  if (detectorTypeEnum == 1) detectorType = InDetDD::PixelBarrel;
174  else if (detectorTypeEnum == 2) detectorType = InDetDD::PixelEndcap;
175  else if (detectorTypeEnum == 3) detectorType = InDetDD::PixelInclined;
176  }
177 
178  auto design = std::make_unique<PixelModuleDesign>(thickness,
179  circuitsPerPhi, circuitsPerEta,
180  columnsPerChip, rowsPerChip,
181  columnsPerChip, rowsPerChip,
182  fullMatrix, carrier,
183  readoutSide, is3D, detectorType);
184 
185 
186  ATH_MSG_DEBUG("readout geo - design : " << design->width() << " " << design->length() << " " << design->thickness() << " " <<design->rows() << " " << design->columns());
187 
188  [[maybe_unused]] auto observePtr = m_detectorManager->addDesign(std::move(design));
189 
190  // Add to map for addModule routine
192 }
193 
194 
195 void PixelGmxInterface::addSensor(const std::string& typeName,
196  std::map<std::string, int> &index,
197  int /*sensitiveId*/,
198  GeoVFullPhysVol *fpv)
199 {
200  //
201  // Get the ATLAS "Offline" wafer identifier
202  //
203  const PixelID *pixelIdHelper = dynamic_cast<const PixelID *>(m_commonItems->getIdHelper());
204  if (not pixelIdHelper){
205  ATH_MSG_ERROR("Failed dynamic_cast to PixelID in PixelGmxInterface::addSensor");
206  return;
207  }
208  Identifier id = pixelIdHelper->wafer_id(index["barrel_endcap"],
209  index["layer_wheel"],
210  index["phi_module"],
211  index["eta_module"]);
212  IdentifierHash hashId = pixelIdHelper->wafer_hash(id);
213  //
214  // Now do our best to check if this is a valid id. If either the gmx file is wrong, or the xml file
215  // defining the allowed id's is wrong, you can get disallowed id's. These cause a crash later
216  // if allowed through. To do the check, we ask for the hash-id of this id. Invalid ids give a
217  // special invalid hash-id (0xFFFFFFFF). But we don't exit the run, to help debug things quicker.
218  //
219  if (!hashId.is_valid()) {
220  ATH_MSG_ERROR("Invalid id for sensitive module " << typeName << " volume with indices");
221  for (const auto& [key, value] : index) {
222  msg() << MSG::ERROR << key << " = " << value << "; ";
223  }
224  msg() << MSG::ERROR << endmsg;
225  ATH_MSG_ERROR("Refusing to make it into a sensitive element. Incompatible gmx and identifier-xml files.");
226  return;
227  }
228 
229  //
230  // Create the detector element and add to the DetectorManager
231  //
232  auto it = m_geometryMap.find(typeName);
233  if(it == m_geometryMap.end()) {
234  ATH_MSG_ERROR("addSensor: Error: Readout sensor type " << typeName << " not found.");
235  throw std::runtime_error("readout sensor type " + typeName + " not found.");
236  }
237  const SiDetectorDesign *design = m_detectorManager->getDesign(it->second);
238  ATH_MSG_VERBOSE("Adding sensor with design: " << typeName << " " << design);
239  if (design == nullptr) {
240  ATH_MSG_ERROR("addSensor: Error: Readout sensor type " << typeName << " not found.");
241  throw std::runtime_error("readout sensor type " + typeName + " not found.");
242  }
243 
245 
246  //
247  // Build up a map-structure for numerology
248  //
249  Wafer module((unsigned int) hashId);
250  std::string errorMessage("");
251  if (!m_moduleTree->add(index["barrel_endcap"],
252  index["layer_wheel"],
253  index["eta_module"],
254  index["phi_module"],
255  module,
256  errorMessage)) {
257  ATH_MSG_ERROR(errorMessage);
258  }
259 
260  return;
261 }
262 
263 
264 std::shared_ptr<const PixelDiodeMatrix> PixelGmxInterface::buildMatrix(double phiPitch, double etaPitch,
265  double phiPitchLong, double phiPitchEnd,
266  double etaPitchLong, double etaPitchEnd,
267  int nPhiLong, int nPhiEnd,
268  int nEtaLong, int nEtaEnd,
269  int circuitsPhi, int circuitsEta,
270  int diodeColPerCirc, int diodeRowPerCirc) const
271 {
272  // checking for unlogical values
273  if (circuitsPhi < 1 or circuitsEta < 1) {
274  ATH_MSG_WARNING("Number of circuits is 0");
275  return nullptr;
276  }
277  if (diodeRowPerCirc < 1 or diodeColPerCirc < 1) {
278  ATH_MSG_WARNING("Number of diodes per circuit is 0");
279  return nullptr;
280  }
281  if (nPhiLong < 0 or nPhiEnd < 0 or nEtaLong < 0 or nEtaEnd < 0) {
282  ATH_MSG_WARNING("Number of long/end cells per circuit is below 0");
283  return nullptr;
284  }
285 
286  // checking and correcting inconsistent values
287  if (nPhiLong == 0 and not (phiPitchLong == 0.0 or phiPitchLong == phiPitch)) {
288  ATH_MSG_DEBUG("nPhiLong is set to 0, but phiPitchLong is neither 0 nor phiPitch! Setting nPhiLong to 1");
289  nPhiLong = 1;
290  }
291  if (nPhiEnd == 0 and not (phiPitchEnd == 0.0 or phiPitchEnd == phiPitch)) {
292  ATH_MSG_DEBUG("nPhiEnd is set to 0, but phiPitchEnd is neither 0 nor phiPitch! Setting nPhiEnd to 1");
293  nPhiEnd = 1;
294  }
295  if (nEtaLong == 0 and not (etaPitchLong == 0.0 or etaPitchLong == etaPitch)) {
296  ATH_MSG_DEBUG("nEtaLong is set to 0, but etaPitchLong is neither 0 nor etaPitch! Setting nEtaLong to 1");
297  nEtaLong = 1;
298  }
299  if (nEtaEnd == 0 and not (etaPitchEnd == 0.0 or etaPitchEnd == etaPitch)) {
300  ATH_MSG_DEBUG("nEtaEnd is set to 0, but etaPitchEnd is neither 0 nor etaPitch! Setting nEtaEnd to 1");
301  nEtaEnd = 1;
302  }
303 
304  /*
305  The naming of internal PixelDiodeMatrix cell objects here follows the
306  convention of cell_XX, where X is N for normal, L for long or E for end.
307  The first index denotes the phi direction, the second eta.
308  */
309 
310  // creation of individual pixels
311  std::shared_ptr<const PixelDiodeMatrix> cell_NN{};
312  std::shared_ptr<const PixelDiodeMatrix> cell_NL{};
313  std::shared_ptr<const PixelDiodeMatrix> cell_NE{};
314  std::shared_ptr<const PixelDiodeMatrix> cell_LN{};
315  std::shared_ptr<const PixelDiodeMatrix> cell_LL{};
316  std::shared_ptr<const PixelDiodeMatrix> cell_LE{};
317  std::shared_ptr<const PixelDiodeMatrix> cell_EN{};
318  std::shared_ptr<const PixelDiodeMatrix> cell_EL{};
319  std::shared_ptr<const PixelDiodeMatrix> cell_EE{};
320 
321  // only filling long/end pixels if needed
322  cell_NN = PixelDiodeMatrix::construct(phiPitch, etaPitch);
323  if (nEtaLong > 0) {cell_NL = PixelDiodeMatrix::construct(phiPitch, etaPitchLong);}
324  if (nEtaEnd > 0) {cell_NE = PixelDiodeMatrix::construct(phiPitch, etaPitchEnd);}
325 
326  if (nPhiLong > 0) {
327  cell_LN = PixelDiodeMatrix::construct(phiPitchLong, etaPitch);
328  if (nEtaLong > 0) {cell_LL = PixelDiodeMatrix::construct(phiPitchLong, etaPitchLong);}
329  if (nEtaEnd > 0) {cell_LE = PixelDiodeMatrix::construct(phiPitchLong, etaPitchEnd);}
330  }
331  if (nPhiEnd > 0) {
332  cell_EN = PixelDiodeMatrix::construct(phiPitchEnd, etaPitch);
333  if (nEtaLong > 0) {cell_EL = PixelDiodeMatrix::construct(phiPitchEnd, etaPitchLong);}
334  if (nEtaEnd > 0) {cell_EE = PixelDiodeMatrix::construct(phiPitchEnd, etaPitchEnd);}
335  }
336 
337  // creation of long/end cell blocks (in case there are more then one long/end per cicuit)
338  if (nPhiLong > 1) {
339  if (cell_LN) {cell_LN = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, nullptr, cell_LN, nPhiLong, nullptr);}
340  if (cell_LL) {cell_LL = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, nullptr, cell_LL, nPhiLong, nullptr);}
341  if (cell_LE) {cell_LE = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, nullptr, cell_LE, nPhiLong, nullptr);}
342  }
343  if (nPhiEnd > 1) {
344  if (cell_EN) {cell_EN = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, nullptr, cell_EN, nPhiEnd, nullptr);}
345  if (cell_EL) {cell_EL = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, nullptr, cell_EL, nPhiEnd, nullptr);}
346  if (cell_EE) {cell_EE = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, nullptr, cell_EE, nPhiEnd, nullptr);}
347  }
348  if (nEtaLong > 1) {
349  if (cell_NL) {cell_NL = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, nullptr, cell_NL, nEtaLong, nullptr);}
350  if (cell_LL) {cell_LL = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, nullptr, cell_LL, nEtaLong, nullptr);}
351  if (cell_EL) {cell_EL = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, nullptr, cell_EL, nEtaLong, nullptr);}
352  }
353  if (nEtaEnd > 1) {
354  if (cell_NE) {cell_NE = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, nullptr, cell_NE, nEtaEnd, nullptr);}
355  if (cell_LE) {cell_LE = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, nullptr, cell_LE, nEtaEnd, nullptr);}
356  if (cell_EE) {cell_EE = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, nullptr, cell_EE, nEtaEnd, nullptr);}
357  }
358 
359  /*
360  The naming of internal PixelDiodeMatrix cell objects here follows the
361  convention of row_XY, where X is for phi N, L or E as before.
362  Y is for eta:
363  - L for a lower chip
364  - M for a middle chip
365  - U for an upper chip
366  The first index denotes the phi direction, the second eta.
367  If just one index is given, it is phi and eta is a full row.
368  */
369 
370  // putting together the single chip rows (eta direction)
371  std::shared_ptr<const PixelDiodeMatrix> fullChipRow_N{};
372  std::shared_ptr<const PixelDiodeMatrix> fullChipRow_L{};
373  std::shared_ptr<const PixelDiodeMatrix> fullChipRow_E{};
374  if (circuitsEta == 1) {
375  // special case of just one circuit in eta direction (no long cells, just end)
376  fullChipRow_N = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, cell_NE, std::move(cell_NN) , diodeColPerCirc - 2*nEtaEnd, cell_NE);
377  if (cell_LN) {fullChipRow_L = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, cell_LE, std::move(cell_LN), diodeColPerCirc - 2*nEtaEnd, cell_LE);}
378  if (cell_EN) {fullChipRow_E = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, cell_EE, std::move(cell_EN), diodeColPerCirc - 2*nEtaEnd, cell_EE);}
379  } else {
380  // rows of individual chips
381  auto singleChipRow_NL = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, cell_NE, cell_NN, diodeColPerCirc -nEtaEnd -nEtaLong, cell_NL);
382  auto singleChipRow_NM = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, cell_NL, cell_NN, diodeColPerCirc -nEtaLong -nEtaLong, cell_NL);
383  auto singleChipRow_NU = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, std::move(cell_NL), std::move(cell_NN), diodeColPerCirc -nEtaLong -nEtaEnd, std::move(cell_NE));
384 
385  std::shared_ptr<const PixelDiodeMatrix> singleChipRow_LL{};
386  std::shared_ptr<const PixelDiodeMatrix> singleChipRow_LM{};
387  std::shared_ptr<const PixelDiodeMatrix> singleChipRow_LU{};
388  if (cell_LN) {
389  singleChipRow_LL = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, cell_LE, cell_LN, diodeColPerCirc -nEtaEnd -nEtaLong, cell_LL);
390  singleChipRow_LM = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, cell_LL, cell_LN, diodeColPerCirc -nEtaLong -nEtaLong, cell_LL);
391  singleChipRow_LU = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, std::move(cell_LL), cell_LN, diodeColPerCirc -nEtaLong -nEtaEnd, std::move(cell_LE));
392  }
393 
394  std::shared_ptr<const PixelDiodeMatrix> singleChipRow_EL{};
395  std::shared_ptr<const PixelDiodeMatrix> singleChipRow_EM{};
396  std::shared_ptr<const PixelDiodeMatrix> singleChipRow_EU{};
397  if (cell_EN) {
398  singleChipRow_EL = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, cell_EE, cell_EN, diodeColPerCirc -nEtaEnd -nEtaLong, cell_EL);
399  singleChipRow_EM = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, cell_EL, cell_EN, diodeColPerCirc -nEtaLong -nEtaLong, cell_EL);
400  singleChipRow_EU = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, std::move(cell_EL), cell_EN, diodeColPerCirc -nEtaLong -nEtaEnd, std::move(cell_EE));
401  }
402 
403  // putting together the single chip rows
404  if (circuitsEta == 2) {
405  // special case of no middle chips in eta (just lower and upper)
406  fullChipRow_N = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, std::move(singleChipRow_NL), std::move(singleChipRow_NU), 1, nullptr);
407  if (cell_LN) {fullChipRow_L = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, std::move(singleChipRow_LL), std::move(singleChipRow_LU), 1, nullptr);}
408  if (cell_EN) {fullChipRow_E = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, std::move(singleChipRow_EL), std::move(singleChipRow_EU), 1, nullptr);}
409  } else {
410  fullChipRow_N = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, std::move(singleChipRow_NL), std::move(singleChipRow_NM), circuitsEta-2, std::move(singleChipRow_NU) );
411  if (cell_LN) {fullChipRow_L = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, std::move(singleChipRow_LL) , std::move(singleChipRow_LM), circuitsEta-2, std::move(singleChipRow_LU));}
412  if (cell_EN) {fullChipRow_E = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, std::move(singleChipRow_EL), std::move(singleChipRow_EM), circuitsEta-2, std::move(singleChipRow_EU));}
413  }
414  }
415 
416  // combining the full eta rows to the full Matrix
417  std::shared_ptr<const PixelDiodeMatrix> fullMatrix{};
418  if (circuitsPhi == 1) {
419  // special case of just one circuit in eta direction (no long cells, just end)
420  fullMatrix = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, fullChipRow_E, std::move(fullChipRow_N), diodeRowPerCirc - 2*nPhiEnd, fullChipRow_E);
421  } else {
422  // columns of individual chips
423  auto singleChipCol_L = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, fullChipRow_E, fullChipRow_N, diodeRowPerCirc -nPhiEnd -nPhiLong, fullChipRow_L);
424  auto singleChipCol_M = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, fullChipRow_L, fullChipRow_N, diodeRowPerCirc -nPhiLong -nPhiLong, fullChipRow_L);
425  auto singleChipCol_U = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, std::move(fullChipRow_L), std::move(fullChipRow_N) , diodeRowPerCirc -nPhiLong -nPhiEnd, std::move(fullChipRow_E));
426 
427  // putting together the single chip rows
428  if (circuitsPhi == 2) {
429  // special case of no middle chips in phi (just lower and upper)
430  fullMatrix = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, std::move(singleChipCol_L), std::move(singleChipCol_U), 1, nullptr);
431  } else {
432  fullMatrix = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, std::move(singleChipCol_L), std::move(singleChipCol_M), circuitsPhi-2, std::move(singleChipCol_U));
433  }
434  }
435 
436  return fullMatrix;
437 }
438 
439 void PixelGmxInterface::buildReadoutGeometryFromSqlite(IRDBAccessSvc * rdbAccessSvc,GeoModelIO::ReadGeoModel* sqlreader){
440 
441  const std::array<std::string,2> sensorTypes{"QuadChip_RD53","SingleChip_RD53"};
442  const std::array<std::string,17> rd53_ParamNames{"circuitsPerEta","circuitsPerPhi","columns","detectorType","is3D","nEtaEndPerSide","nEtaLongPerSide","nPhiEndPerSide","nPhiLongPerSide","pitchEta","pitchEtaEnd","pitchEtaLong","pitchPhi","pitchPhiEnd","pitchPhiLong","rows","thickness"};
443 
444  for(const std::string & sType:sensorTypes){
445  IRDBRecordset_ptr rd53 = rdbAccessSvc->getRecordsetPtr(sType,"");
446  if(rd53->size() !=0){
447  for (unsigned int iR =0;iR<rd53->size();iR++){
448  std::map<std::string,std::string> rd53_Map;
449  for(const std::string & paramName:rd53_ParamNames){
450  std::string paramValue = (*rd53)[iR]->getString(paramName);
451  rd53_Map[paramName] = std::move(paramValue);
452  }
453  std::string rd35_Name = (*rd53)[iR]->getString("SensorType");
454  makePixelModule(rd35_Name,rd53_Map);
455  }
456  }
457  else ATH_MSG_WARNING("Could not retrieve "<<sType<<" table");
458  }
459 
460  //Now, loop over the FullPhysVols and create the SiDetectorElements
461  //lots of string parsing...
462  const std::array<std::string,5> fields{"barrel_endcap","layer_wheel","phi_module","eta_module","side"};
463  //First, find which name the tables are in the file under (depends upon the plugin used to create the input file)
464  //sort these in order of precedence - ITkPlugin, then ITkPixelPlugin, then GeoModelXMLPlugin
465  const std::array<std::string,3> publishers({"ITk","ITkPixel","GeoModelXML"});
466  //The below is a map of string keys which will contain all the Identifier/DetElement relevant info, and the associated FullPhysVol
467  // (once filled from the published table in the SQLite)
468  std::map<std::string, GeoFullPhysVol*> mapFPV;
469  for (auto & iPub : publishers){
470  //setting the "checkTable" option to true, so that an empty map will be returned if not found and we can try the next one
471  mapFPV = sqlreader->getPublishedNodes<std::string, GeoFullPhysVol*>(iPub,true);
472  if (!mapFPV.empty()) {
473  ATH_MSG_DEBUG("Using FPV tables from publisher "<<iPub);
474  break;
475  }
476  }
477  if (mapFPV.empty()) ATH_MSG_ERROR("Could not find any FPV tables under the expected names: "<<publishers);
478 
479  for (const auto&[fullPhysVolInfoString, fullPhysVolPointer] : mapFPV){
480  //find the name of the corresponding detector design type
481  size_t startRG = fullPhysVolInfoString.find("RD53_");
482  if(startRG==std::string::npos){
483  ATH_MSG_DEBUG("GeoFullPhysVol "<<fullPhysVolInfoString<<" does not have the expected format. Skipping");
484  continue;
485  }
486  std::string typeName = fullPhysVolInfoString.substr(startRG);
487  std::map<std::string, int> index;
488  for (const std::string & field:fields){
489  size_t first = fullPhysVolInfoString.find(field+"_");
490  size_t last = fullPhysVolInfoString.find('_',first+field.size()+1);//start looking only after end of first delimiter (plus 1 for the "_" appended) ends
491  if(first==std::string::npos || last==std::string::npos){
492  ATH_MSG_DEBUG("Could not extract "<<field<<" from "<<fullPhysVolInfoString<<". Skipping");
493  continue;
494  }
495  std::string strNew = fullPhysVolInfoString.substr(first+field.size()+1,last-(first+field.size()+1));
496  index[field] = std::stoi(strNew);
497  }
498 
499  addSensor(typeName,index,0,fullPhysVolPointer);
500  }
501 
502 }
503 
505  std::map<std::string, int> &index,
506  GeoVFullPhysVol *fpv,
507  GeoAlignableTransform *transform)
508 {
509  ATH_MSG_DEBUG("addAlignable called");
510  const PixelID *pixelIdHelper = dynamic_cast<const PixelID *> (m_commonItems->getIdHelper());
511  if (not pixelIdHelper){
512  ATH_MSG_ERROR("Dynamic cast to PixelID failed in PixelGmxInterface::addAlignable");
513  return;
514  }
515  Identifier id;
516  switch (level) {
517  case 0:
518  id = pixelIdHelper->wafer_id(index["barrel_endcap"],
519  index["layer_wheel"],
520  index["phi_module"],
521  index["eta_module"],
522  index["side"]);
523  break;
524  case 1:
525  id = pixelIdHelper->wafer_id(index["barrel_endcap"],
526  index["layer_wheel"],
527  index["phi_module"],
528  index["eta_module"],
529  0);
530  break;
531  case 2:
532  id = pixelIdHelper->wafer_id(index["barrel_endcap"],
533  index["layer_wheel"],
534  0,
535  0,
536  0);
537  break;
538  case 3:
539  id = pixelIdHelper->wafer_id(index["barrel_endcap"],
540  0,
541  0,
542  0,
543  0);
544  break;
545  default:
546  throw GaudiException("Unknown level " + std::to_string(level) + " for alignment in addAlignable",
547  "PixelGmxInterface::addAlignable", StatusCode::FAILURE);
548  break;
549  }
551 }
552 
553 
554 } // namespace ITk
555 } // namespace InDetDD
IRDBAccessSvc::getRecordsetPtr
virtual IRDBRecordset_ptr getRecordsetPtr(const std::string &node, const std::string &tag, const std::string &tag2node="", const std::string &connName="ATLASDD")=0
Provides access to the Recordset object containing HVS-tagged data.
InDetDD::SiCommonItems::getIdHelper
const AtlasDetectorID * getIdHelper() const
Definition: SiCommonItems.h:83
index
Definition: index.py:1
InDetDD::ITk::PixelGmxInterface::addAlignable
virtual void addAlignable(int level, std::map< std::string, int > &index, GeoVFullPhysVol *fpv, GeoAlignableTransform *transform) override final
Definition: PixelGmxInterface.cxx:504
InDetDD::SiDetectorManager::numDesigns
int numDesigns() const
Definition: SiDetectorManager.cxx:140
skel.it
it
Definition: skel.GENtoEVGEN.py:396
InDetDD::PixelDiodeMatrix::construct
static std::shared_ptr< const PixelDiodeMatrix > construct(double phiWidth, double etaWidth)
Construct method for just a single cell.
Definition: PixelDiodeMatrix.cxx:14
PixelGmxInterface.h
InDetDD::SiDetectorManager::addDesign
const SiDetectorDesign * addDesign(std::unique_ptr< const SiDetectorDesign > &&)
Access to module design; returns an observer pointer.
Definition: SiDetectorManager.cxx:134
athena.value
value
Definition: athena.py:124
ReadOfcFromCool.field
field
Definition: ReadOfcFromCool.py:48
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
InDetDD::ITk::PixelGmxInterface::m_moduleTree
WaferTree * m_moduleTree
Definition: PixelGmxInterface.h:68
InDetDD::PixelInclined
@ PixelInclined
Definition: DetectorDesign.h:46
InDetDD::ITk::PixelGmxInterface::m_geometryMap
std::map< std::string, int > m_geometryMap
Definition: PixelGmxInterface.h:61
InDetDD::PixelEndcap
@ PixelEndcap
Definition: DetectorDesign.h:46
python.iconfTool.models.loaders.level
level
Definition: loaders.py:20
InDetDD::PixelDiodeMatrix::phiDir
@ phiDir
Definition: PixelDiodeMatrix.h:97
InDetDD::ITk::PixelGmxInterface::sensorId
virtual int sensorId(std::map< std::string, int > &index) const override
Definition: PixelGmxInterface.cxx:44
PixelConditionsData::getParameter
std::vector< T > getParameter(const std::string &varName, const std::vector< std::string > &buffer)
Definition: PixelConditionsDataStringUtils.h:51
SiHitIdHelper.h
python.PyAthena.module
module
Definition: PyAthena.py:131
PixelDetectorManager.h
IRDBAccessSvc.h
Definition of the abstract IRDBAccessSvc interface.
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
InDetDD::DetectorType
DetectorType
Definition: DetectorDesign.h:45
IRDBAccessSvc
IRDBAccessSvc is an abstract interface to the athena service that provides the following functionalit...
Definition: IRDBAccessSvc.h:42
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
SiCommonItems.h
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Wafer
Definition: WaferTree.h:27
BarrelEndcap::add
bool add(int bec, int ld, int eta, int phi, int side, Wafer &wafer, std::string &errorMessage)
Definition: WaferTree.cxx:55
InDetDD::SiDetectorManager::getDesign
const SiDetectorDesign * getDesign(int i) const
Definition: SiDetectorManager.cxx:146
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
InDetDD::ITk::PixelGmxInterface::buildReadoutGeometryFromSqlite
void buildReadoutGeometryFromSqlite(IRDBAccessSvc *rdbAccessSvc, GeoModelIO::ReadGeoModel *sqlreader)
Definition: PixelGmxInterface.cxx:439
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
InDetDD::ITk::PixelGmxInterface::m_commonItems
SiCommonItems * m_commonItems
Definition: PixelGmxInterface.h:67
IRDBRecordset_ptr
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition: IRDBAccessSvc.h:25
AthMessaging::msg
MsgStream & msg() const
The standard message stream.
Definition: AthMessaging.h:164
InDetDD::PixelDetectorManager::addAlignableTransform
virtual void addAlignableTransform(int level, const Identifier &id, GeoAlignableTransform *xf, const GeoVFullPhysVol *child)
Add alignable transforms.
Definition: PixelDetectorManager.cxx:262
IdentifierHash::is_valid
bool is_valid() const
Check if id is in a valid state.
WaferTree.h
InDetDD::ITk::PixelGmxInterface::PixelGmxInterface
PixelGmxInterface(PixelDetectorManager *detectorManager, SiCommonItems *commonItems, WaferTree *moduleTree)
Definition: PixelGmxInterface.cxx:34
InDetDD::PixelDetectorManager
Definition: PixelDetectorManager.h:47
ITk
Definition: ITkPixelOfflineCalibCondAlg.cxx:14
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:220
InDetDD::SiCommonItems
Definition: SiCommonItems.h:45
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
InDetDD::PixelBarrel
@ PixelBarrel
Definition: DetectorDesign.h:46
InDetDD::SiDetectorElement
Definition: SiDetectorElement.h:109
InDetDD::ITk::PixelGmxInterface::makePixelModule
void makePixelModule(const std::string &typeName, const std::map< std::string, std::string > &parameters)
Definition: PixelGmxInterface.cxx:102
SiDetectorElement.h
InDetDD::ITk::PixelGmxInterface::buildMatrix
std::shared_ptr< const PixelDiodeMatrix > buildMatrix(double phiPitch, double etaPitch, double phiPitchLong, double phiPitchEnd, double etaPitchLong, double etaPitchEnd, int nPhiLong, int nPhiEnd, int nEtaLong, int nEtaEnd, int circuitsPhi, int circuitsEta, int diodeColPerCirc, int diodeRowPerCirc) const
Definition: PixelGmxInterface.cxx:264
InDetDD::ITk::PixelGmxInterface::m_detectorManager
PixelDetectorManager * m_detectorManager
Definition: PixelGmxInterface.h:66
DeMoScan.index
string index
Definition: DeMoScan.py:364
PixelDiodeMatrix.h
IRDBRecord.h
Definition of the abstract IRDBRecord interface.
InDetDD::CarrierType
CarrierType
Definition: InDetDD_Defs.h:17
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
InDetDD
Message Stream Member.
Definition: FakeTrackBuilder.h:8
PixelModuleDesign.h
DeMoScan.first
bool first
Definition: DeMoScan.py:536
SiHitIdHelper::GetHelper
static const SiHitIdHelper * GetHelper()
Definition: SiHitIdHelper.cxx:19
physics_parameters.parameters
parameters
Definition: physics_parameters.py:144
ReadCalibFromCool.typeName
typeName
Definition: ReadCalibFromCool.py:477
InDetDD::ITk::PixelGmxInterface::addSensorType
virtual void addSensorType(const std::string &clas, const std::string &typeName, const std::map< std::string, std::string > &parameters) override
Definition: PixelGmxInterface.cxx:87
CaloCondBlobAlgs_fillNoiseFromASCII.fields
fields
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:106
InDetDD::ITk::PixelGmxInterface::addSensor
virtual void addSensor(const std::string &typeName, std::map< std::string, int > &index, int sequentialId, GeoVFullPhysVol *fpv) override
Definition: PixelGmxInterface.cxx:195
IRDBRecordset.h
Definition of the abstract IRDBRecordset interface.
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::SiDetectorDesign
Definition: SiDetectorDesign.h:50
SiHitIdHelper::buildHitId
int buildHitId(const int, const int, const int, const int, const int, const int) const
Definition: SiHitIdHelper.cxx:118
PixelID
Definition: PixelID.h:67
SiDetectorDesign.h
InDetDD::electrons
@ electrons
Definition: InDetDD_Defs.h:17
InDetDD::PixelDetectorManager::addDetectorElement
virtual void addDetectorElement(SiDetectorElement *element) override
Add elememts.
Definition: PixelDetectorManager.cxx:121
InDetDD::PixelDiodeMatrix::etaDir
@ etaDir
Definition: PixelDiodeMatrix.h:97
WaferTree
Definition: WaferTree.h:74
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
Identifier
Definition: IdentifierFieldParser.cxx:14