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  bool phiSymmetric{true};
127  bool etaSymmetric{true};
128  bool depthSymmetric{true};
129 
130  // read parameters
131  getParameter(typeName, parameters, "circuitsPerEta", circuitsPerEta);
132  getParameter(typeName, parameters, "circuitsPerPhi", circuitsPerPhi);
133  getParameter(typeName, parameters, "thickness", thickness);
134  getParameter(typeName, parameters, "is3D", is3D);
135  getParameter(typeName, parameters, "rows", rowsPerChip);
136  getParameter(typeName, parameters, "columns", columnsPerChip);
137  getParameter(typeName, parameters, "pitchEta", pitchEta);
138  getParameter(typeName, parameters, "pitchPhi", pitchPhi);
139  getParameter(typeName, parameters, "pitchEtaLong", pitchEtaLong);
140  getParameter(typeName, parameters, "pitchPhiLong", pitchPhiLong);
141  getParameter(typeName, parameters, "pitchEtaEnd", pitchEtaEnd);
142  getParameter(typeName, parameters, "pitchPhiEnd", pitchPhiEnd);
143  getParameter(typeName, parameters, "nPhiLongPerSide", nPhiLongPerSide);
144  getParameter(typeName, parameters, "nEtaLongPerSide", nEtaLongPerSide);
145  getParameter(typeName, parameters, "nPhiEndPerSide", nPhiEndPerSide);
146  getParameter(typeName, parameters, "nEtaEndPerSide", nEtaEndPerSide);
147 
148  checkParameter(typeName, parameters, "phiSymmetric", phiSymmetric);
149  checkParameter(typeName, parameters, "etaSymmetric", etaSymmetric);
150  checkParameter(typeName, parameters, "depthSymmetric", depthSymmetric);
151 
152  //
153  // Make Module Design and add to DetectorManager
154  //
155  std::shared_ptr<const PixelDiodeMatrix> fullMatrix = buildMatrix(pitchPhi, pitchEta,
156  pitchPhiLong, pitchPhiEnd,
157  pitchEtaLong, pitchEtaEnd,
158  nPhiLongPerSide, nPhiEndPerSide,
159  nEtaLongPerSide, nEtaEndPerSide,
160  circuitsPerPhi, circuitsPerEta,
161  columnsPerChip, rowsPerChip);
162 
163  ATH_MSG_DEBUG("fullMatrix = buildMatrix(" << pitchPhi << ", " << pitchEta << ", "
164  << pitchPhiLong << ", " << pitchPhiEnd << ", "
165  << pitchEtaLong << ", " << pitchEtaEnd << ", "
166  << nPhiLongPerSide << ", " << nPhiEndPerSide << ", "
167  << nEtaLongPerSide << ", " << nEtaEndPerSide << ", "
168  << circuitsPerPhi << ", " << circuitsPerEta << ", "
169  << columnsPerChip << ", " << rowsPerChip << ")");
170  ATH_MSG_DEBUG("readout geo - design " << thickness << " "
171  << circuitsPerPhi << " " << circuitsPerEta << " "
172  << columnsPerChip << " " << rowsPerChip << " "
173  << columnsPerChip << " " << rowsPerChip << " "
174  << carrier << " " << readoutSide);
175 
176  //For optionally setting PixelBarrel,PixelEndcap,PixelInclined
177  //(so far) primarily useful for the latter to avoid orientation warnings
178  InDetDD::DetectorType detectorType{InDetDD::PixelBarrel}; // TODO: we should probably fail and not default to barrel here.
179  int detectorTypeEnum = 0;
180  if (checkParameter(typeName, parameters, "detectorType", detectorTypeEnum)) {
181  if (detectorTypeEnum == 1) detectorType = InDetDD::PixelBarrel;
182  else if (detectorTypeEnum == 2) detectorType = InDetDD::PixelEndcap;
183  else if (detectorTypeEnum == 3) detectorType = InDetDD::PixelInclined;
184  }
185 
186  auto design = std::make_unique<PixelModuleDesign>(thickness,
187  phiSymmetric, etaSymmetric, depthSymmetric,
188  circuitsPerPhi, circuitsPerEta,
189  columnsPerChip, rowsPerChip,
190  columnsPerChip, rowsPerChip,
191  fullMatrix, carrier,
192  readoutSide, is3D, detectorType);
193 
194 
195  ATH_MSG_DEBUG("readout geo - design : " << design->width() << " " << design->length() << " " << design->thickness() << " " <<design->rows() << " " << design->columns());
196 
197  [[maybe_unused]] auto observePtr = m_detectorManager->addDesign(std::move(design));
198 
199  // Add to map for addModule routine
201 }
202 
203 
204 void PixelGmxInterface::addSensor(const std::string& typeName,
205  std::map<std::string, int> &index,
206  int /*sensitiveId*/,
207  GeoVFullPhysVol *fpv)
208 {
209  //
210  // Get the ATLAS "Offline" wafer identifier
211  //
212  const PixelID *pixelIdHelper = dynamic_cast<const PixelID *>(m_commonItems->getIdHelper());
213  if (not pixelIdHelper){
214  ATH_MSG_ERROR("Failed dynamic_cast to PixelID in PixelGmxInterface::addSensor");
215  return;
216  }
217  Identifier id = pixelIdHelper->wafer_id(index["barrel_endcap"],
218  index["layer_wheel"],
219  index["phi_module"],
220  index["eta_module"]);
221  IdentifierHash hashId = pixelIdHelper->wafer_hash(id);
222  //
223  // Now do our best to check if this is a valid id. If either the gmx file is wrong, or the xml file
224  // defining the allowed id's is wrong, you can get disallowed id's. These cause a crash later
225  // if allowed through. To do the check, we ask for the hash-id of this id. Invalid ids give a
226  // special invalid hash-id (0xFFFFFFFF). But we don't exit the run, to help debug things quicker.
227  //
228  if (!hashId.is_valid()) {
229  ATH_MSG_ERROR("Invalid id for sensitive module " << typeName << " volume with indices");
230  for (const auto& [key, value] : index) {
231  msg() << MSG::ERROR << key << " = " << value << "; ";
232  }
233  msg() << MSG::ERROR << endmsg;
234  ATH_MSG_ERROR("Refusing to make it into a sensitive element. Incompatible gmx and identifier-xml files.");
235  return;
236  }
237 
238  //
239  // Create the detector element and add to the DetectorManager
240  //
241  auto it = m_geometryMap.find(typeName);
242  if(it == m_geometryMap.end()) {
243  ATH_MSG_ERROR("addSensor: Error: Readout sensor type " << typeName << " not found.");
244  throw std::runtime_error("readout sensor type " + typeName + " not found.");
245  }
246  const SiDetectorDesign *design = m_detectorManager->getDesign(it->second);
247  ATH_MSG_VERBOSE("Adding sensor with design: " << typeName << " " << design);
248  if (design == nullptr) {
249  ATH_MSG_ERROR("addSensor: Error: Readout sensor type " << typeName << " not found.");
250  throw std::runtime_error("readout sensor type " + typeName + " not found.");
251  }
252 
254 
255  //
256  // Build up a map-structure for numerology
257  //
258  Wafer module((unsigned int) hashId);
259  std::string errorMessage("");
260  if (!m_moduleTree->add(index["barrel_endcap"],
261  index["layer_wheel"],
262  index["eta_module"],
263  index["phi_module"],
264  module,
265  errorMessage)) {
266  ATH_MSG_ERROR(errorMessage);
267  }
268 
269  return;
270 }
271 
272 
273 std::shared_ptr<const PixelDiodeMatrix> PixelGmxInterface::buildMatrix(double phiPitch, double etaPitch,
274  double phiPitchLong, double phiPitchEnd,
275  double etaPitchLong, double etaPitchEnd,
276  int nPhiLong, int nPhiEnd,
277  int nEtaLong, int nEtaEnd,
278  int circuitsPhi, int circuitsEta,
279  int diodeColPerCirc, int diodeRowPerCirc) const
280 {
281  // checking for unlogical values
282  if (circuitsPhi < 1 or circuitsEta < 1) {
283  ATH_MSG_WARNING("Number of circuits is 0");
284  return nullptr;
285  }
286  if (diodeRowPerCirc < 1 or diodeColPerCirc < 1) {
287  ATH_MSG_WARNING("Number of diodes per circuit is 0");
288  return nullptr;
289  }
290  if (nPhiLong < 0 or nPhiEnd < 0 or nEtaLong < 0 or nEtaEnd < 0) {
291  ATH_MSG_WARNING("Number of long/end cells per circuit is below 0");
292  return nullptr;
293  }
294 
295  // checking and correcting inconsistent values
296  if (nPhiLong == 0 and not (phiPitchLong == 0.0 or phiPitchLong == phiPitch)) {
297  ATH_MSG_DEBUG("nPhiLong is set to 0, but phiPitchLong is neither 0 nor phiPitch! Setting nPhiLong to 1");
298  nPhiLong = 1;
299  }
300  if (nPhiEnd == 0 and not (phiPitchEnd == 0.0 or phiPitchEnd == phiPitch)) {
301  ATH_MSG_DEBUG("nPhiEnd is set to 0, but phiPitchEnd is neither 0 nor phiPitch! Setting nPhiEnd to 1");
302  nPhiEnd = 1;
303  }
304  if (nEtaLong == 0 and not (etaPitchLong == 0.0 or etaPitchLong == etaPitch)) {
305  ATH_MSG_DEBUG("nEtaLong is set to 0, but etaPitchLong is neither 0 nor etaPitch! Setting nEtaLong to 1");
306  nEtaLong = 1;
307  }
308  if (nEtaEnd == 0 and not (etaPitchEnd == 0.0 or etaPitchEnd == etaPitch)) {
309  ATH_MSG_DEBUG("nEtaEnd is set to 0, but etaPitchEnd is neither 0 nor etaPitch! Setting nEtaEnd to 1");
310  nEtaEnd = 1;
311  }
312 
313  /*
314  The naming of internal PixelDiodeMatrix cell objects here follows the
315  convention of cell_XX, where X is N for normal, L for long or E for end.
316  The first index denotes the phi direction, the second eta.
317  */
318 
319  // creation of individual pixels
320  std::shared_ptr<const PixelDiodeMatrix> cell_NN{};
321  std::shared_ptr<const PixelDiodeMatrix> cell_NL{};
322  std::shared_ptr<const PixelDiodeMatrix> cell_NE{};
323  std::shared_ptr<const PixelDiodeMatrix> cell_LN{};
324  std::shared_ptr<const PixelDiodeMatrix> cell_LL{};
325  std::shared_ptr<const PixelDiodeMatrix> cell_LE{};
326  std::shared_ptr<const PixelDiodeMatrix> cell_EN{};
327  std::shared_ptr<const PixelDiodeMatrix> cell_EL{};
328  std::shared_ptr<const PixelDiodeMatrix> cell_EE{};
329 
330  // only filling long/end pixels if needed
331  cell_NN = PixelDiodeMatrix::construct(phiPitch, etaPitch);
332  if (nEtaLong > 0) {cell_NL = PixelDiodeMatrix::construct(phiPitch, etaPitchLong);}
333  if (nEtaEnd > 0) {cell_NE = PixelDiodeMatrix::construct(phiPitch, etaPitchEnd);}
334 
335  if (nPhiLong > 0) {
336  cell_LN = PixelDiodeMatrix::construct(phiPitchLong, etaPitch);
337  if (nEtaLong > 0) {cell_LL = PixelDiodeMatrix::construct(phiPitchLong, etaPitchLong);}
338  if (nEtaEnd > 0) {cell_LE = PixelDiodeMatrix::construct(phiPitchLong, etaPitchEnd);}
339  }
340  if (nPhiEnd > 0) {
341  cell_EN = PixelDiodeMatrix::construct(phiPitchEnd, etaPitch);
342  if (nEtaLong > 0) {cell_EL = PixelDiodeMatrix::construct(phiPitchEnd, etaPitchLong);}
343  if (nEtaEnd > 0) {cell_EE = PixelDiodeMatrix::construct(phiPitchEnd, etaPitchEnd);}
344  }
345 
346  // creation of long/end cell blocks (in case there are more then one long/end per cicuit)
347  if (nPhiLong > 1) {
348  if (cell_LN) {cell_LN = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, nullptr, cell_LN, nPhiLong, nullptr);}
349  if (cell_LL) {cell_LL = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, nullptr, cell_LL, nPhiLong, nullptr);}
350  if (cell_LE) {cell_LE = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, nullptr, cell_LE, nPhiLong, nullptr);}
351  }
352  if (nPhiEnd > 1) {
353  if (cell_EN) {cell_EN = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, nullptr, cell_EN, nPhiEnd, nullptr);}
354  if (cell_EL) {cell_EL = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, nullptr, cell_EL, nPhiEnd, nullptr);}
355  if (cell_EE) {cell_EE = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, nullptr, cell_EE, nPhiEnd, nullptr);}
356  }
357  if (nEtaLong > 1) {
358  if (cell_NL) {cell_NL = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, nullptr, cell_NL, nEtaLong, nullptr);}
359  if (cell_LL) {cell_LL = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, nullptr, cell_LL, nEtaLong, nullptr);}
360  if (cell_EL) {cell_EL = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, nullptr, cell_EL, nEtaLong, nullptr);}
361  }
362  if (nEtaEnd > 1) {
363  if (cell_NE) {cell_NE = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, nullptr, cell_NE, nEtaEnd, nullptr);}
364  if (cell_LE) {cell_LE = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, nullptr, cell_LE, nEtaEnd, nullptr);}
365  if (cell_EE) {cell_EE = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, nullptr, cell_EE, nEtaEnd, nullptr);}
366  }
367 
368  /*
369  The naming of internal PixelDiodeMatrix cell objects here follows the
370  convention of row_XY, where X is for phi N, L or E as before.
371  Y is for eta:
372  - L for a lower chip
373  - M for a middle chip
374  - U for an upper chip
375  The first index denotes the phi direction, the second eta.
376  If just one index is given, it is phi and eta is a full row.
377  */
378 
379  // putting together the single chip rows (eta direction)
380  std::shared_ptr<const PixelDiodeMatrix> fullChipRow_N{};
381  std::shared_ptr<const PixelDiodeMatrix> fullChipRow_L{};
382  std::shared_ptr<const PixelDiodeMatrix> fullChipRow_E{};
383  if (circuitsEta == 1) {
384  // special case of just one circuit in eta direction (no long cells, just end)
385  fullChipRow_N = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, cell_NE, std::move(cell_NN) , diodeColPerCirc - 2*nEtaEnd, cell_NE);
386  if (cell_LN) {fullChipRow_L = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, cell_LE, std::move(cell_LN), diodeColPerCirc - 2*nEtaEnd, cell_LE);}
387  if (cell_EN) {fullChipRow_E = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, cell_EE, std::move(cell_EN), diodeColPerCirc - 2*nEtaEnd, cell_EE);}
388  } else {
389  // rows of individual chips
390  auto singleChipRow_NL = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, cell_NE, cell_NN, diodeColPerCirc -nEtaEnd -nEtaLong, cell_NL);
391  auto singleChipRow_NM = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, cell_NL, cell_NN, diodeColPerCirc -nEtaLong -nEtaLong, cell_NL);
392  auto singleChipRow_NU = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, std::move(cell_NL), std::move(cell_NN), diodeColPerCirc -nEtaLong -nEtaEnd, std::move(cell_NE));
393 
394  std::shared_ptr<const PixelDiodeMatrix> singleChipRow_LL{};
395  std::shared_ptr<const PixelDiodeMatrix> singleChipRow_LM{};
396  std::shared_ptr<const PixelDiodeMatrix> singleChipRow_LU{};
397  if (cell_LN) {
398  singleChipRow_LL = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, cell_LE, cell_LN, diodeColPerCirc -nEtaEnd -nEtaLong, cell_LL);
399  singleChipRow_LM = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, cell_LL, cell_LN, diodeColPerCirc -nEtaLong -nEtaLong, cell_LL);
400  singleChipRow_LU = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, std::move(cell_LL), cell_LN, diodeColPerCirc -nEtaLong -nEtaEnd, std::move(cell_LE));
401  }
402 
403  std::shared_ptr<const PixelDiodeMatrix> singleChipRow_EL{};
404  std::shared_ptr<const PixelDiodeMatrix> singleChipRow_EM{};
405  std::shared_ptr<const PixelDiodeMatrix> singleChipRow_EU{};
406  if (cell_EN) {
407  singleChipRow_EL = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, cell_EE, cell_EN, diodeColPerCirc -nEtaEnd -nEtaLong, cell_EL);
408  singleChipRow_EM = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, cell_EL, cell_EN, diodeColPerCirc -nEtaLong -nEtaLong, cell_EL);
409  singleChipRow_EU = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, std::move(cell_EL), cell_EN, diodeColPerCirc -nEtaLong -nEtaEnd, std::move(cell_EE));
410  }
411 
412  // putting together the single chip rows
413  if (circuitsEta == 2) {
414  // special case of no middle chips in eta (just lower and upper)
415  fullChipRow_N = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, std::move(singleChipRow_NL), std::move(singleChipRow_NU), 1, nullptr);
416  if (cell_LN) {fullChipRow_L = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, std::move(singleChipRow_LL), std::move(singleChipRow_LU), 1, nullptr);}
417  if (cell_EN) {fullChipRow_E = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, std::move(singleChipRow_EL), std::move(singleChipRow_EU), 1, nullptr);}
418  } else {
419  fullChipRow_N = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, std::move(singleChipRow_NL), std::move(singleChipRow_NM), circuitsEta-2, std::move(singleChipRow_NU) );
420  if (cell_LN) {fullChipRow_L = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, std::move(singleChipRow_LL) , std::move(singleChipRow_LM), circuitsEta-2, std::move(singleChipRow_LU));}
421  if (cell_EN) {fullChipRow_E = PixelDiodeMatrix::construct(PixelDiodeMatrix::etaDir, std::move(singleChipRow_EL), std::move(singleChipRow_EM), circuitsEta-2, std::move(singleChipRow_EU));}
422  }
423  }
424 
425  // combining the full eta rows to the full Matrix
426  std::shared_ptr<const PixelDiodeMatrix> fullMatrix{};
427  if (circuitsPhi == 1) {
428  // special case of just one circuit in eta direction (no long cells, just end)
429  fullMatrix = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, fullChipRow_E, std::move(fullChipRow_N), diodeRowPerCirc - 2*nPhiEnd, fullChipRow_E);
430  } else {
431  // columns of individual chips
432  auto singleChipCol_L = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, fullChipRow_E, fullChipRow_N, diodeRowPerCirc -nPhiEnd -nPhiLong, fullChipRow_L);
433  auto singleChipCol_M = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, fullChipRow_L, fullChipRow_N, diodeRowPerCirc -nPhiLong -nPhiLong, fullChipRow_L);
434  auto singleChipCol_U = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, std::move(fullChipRow_L), std::move(fullChipRow_N) , diodeRowPerCirc -nPhiLong -nPhiEnd, std::move(fullChipRow_E));
435 
436  // putting together the single chip rows
437  if (circuitsPhi == 2) {
438  // special case of no middle chips in phi (just lower and upper)
439  fullMatrix = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, std::move(singleChipCol_L), std::move(singleChipCol_U), 1, nullptr);
440  } else {
441  fullMatrix = PixelDiodeMatrix::construct(PixelDiodeMatrix::phiDir, std::move(singleChipCol_L), std::move(singleChipCol_M), circuitsPhi-2, std::move(singleChipCol_U));
442  }
443  }
444 
445  return fullMatrix;
446 }
447 
448 void PixelGmxInterface::buildReadoutGeometryFromSqlite(IRDBAccessSvc * rdbAccessSvc,GeoModelIO::ReadGeoModel* sqlreader){
449 
450  const std::array<std::string,2> sensorTypes{"QuadChip_RD53","SingleChip_RD53"};
451  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"};
452 
453  for(const std::string & sType:sensorTypes){
454  IRDBRecordset_ptr rd53 = rdbAccessSvc->getRecordsetPtr(sType,"");
455  if(rd53->size() !=0){
456  for (unsigned int iR =0;iR<rd53->size();iR++){
457  std::map<std::string,std::string> rd53_Map;
458  for(const std::string & paramName:rd53_ParamNames){
459  std::string paramValue = (*rd53)[iR]->getString(paramName);
460  rd53_Map[paramName] = std::move(paramValue);
461  }
462  std::string rd35_Name = (*rd53)[iR]->getString("SensorType");
463  makePixelModule(rd35_Name,rd53_Map);
464  }
465  }
466  else ATH_MSG_WARNING("Could not retrieve "<<sType<<" table");
467  }
468 
469  //Now, loop over the FullPhysVols and create the SiDetectorElements
470  //lots of string parsing...
471  const std::array<std::string,5> fields{"barrel_endcap","layer_wheel","phi_module","eta_module","side"};
472  //First, find which name the tables are in the file under (depends upon the plugin used to create the input file)
473  //sort these in order of precedence - ITkPlugin, then ITkPixelPlugin, then GeoModelXMLPlugin
474  const std::array<std::string,3> publishers({"ITk","ITkPixel","GeoModelXML"});
475  //The below is a map of string keys which will contain all the Identifier/DetElement relevant info, and the associated FullPhysVol
476  // (once filled from the published table in the SQLite)
477  std::map<std::string, GeoFullPhysVol*> mapFPV;
478  for (auto & iPub : publishers){
479  //setting the "checkTable" option to true, so that an empty map will be returned if not found and we can try the next one
480  mapFPV = sqlreader->getPublishedNodes<std::string, GeoFullPhysVol*>(iPub,true);
481  if (!mapFPV.empty()) {
482  ATH_MSG_DEBUG("Using FPV tables from publisher "<<iPub);
483  break;
484  }
485  }
486  if (mapFPV.empty()) ATH_MSG_ERROR("Could not find any FPV tables under the expected names: "<<publishers);
487 
488  for (const auto&[fullPhysVolInfoString, fullPhysVolPointer] : mapFPV){
489  //find the name of the corresponding detector design type
490  size_t startRG = fullPhysVolInfoString.find("RD53_");
491  if(startRG==std::string::npos){
492  ATH_MSG_DEBUG("GeoFullPhysVol "<<fullPhysVolInfoString<<" does not have the expected format. Skipping");
493  continue;
494  }
495  std::string typeName = fullPhysVolInfoString.substr(startRG);
496  std::map<std::string, int> index;
497  for (const std::string & field:fields){
498  size_t first = fullPhysVolInfoString.find(field+"_");
499  size_t last = fullPhysVolInfoString.find('_',first+field.size()+1);//start looking only after end of first delimiter (plus 1 for the "_" appended) ends
500  if(first==std::string::npos || last==std::string::npos){
501  ATH_MSG_DEBUG("Could not extract "<<field<<" from "<<fullPhysVolInfoString<<". Skipping");
502  continue;
503  }
504  std::string strNew = fullPhysVolInfoString.substr(first+field.size()+1,last-(first+field.size()+1));
505  index[field] = std::stoi(strNew);
506  }
507 
508  addSensor(typeName,index,0,fullPhysVolPointer);
509  }
510 
511 }
512 
514  std::map<std::string, int> &index,
515  GeoVFullPhysVol *fpv,
516  GeoAlignableTransform *transform)
517 {
518  ATH_MSG_DEBUG("addAlignable called");
519  const PixelID *pixelIdHelper = dynamic_cast<const PixelID *> (m_commonItems->getIdHelper());
520  if (not pixelIdHelper){
521  ATH_MSG_ERROR("Dynamic cast to PixelID failed in PixelGmxInterface::addAlignable");
522  return;
523  }
524  Identifier id;
525  switch (level) {
526  case 0:
527  id = pixelIdHelper->wafer_id(index["barrel_endcap"],
528  index["layer_wheel"],
529  index["phi_module"],
530  index["eta_module"],
531  index["side"]);
532  break;
533  case 1:
534  id = pixelIdHelper->wafer_id(index["barrel_endcap"],
535  index["layer_wheel"],
536  index["phi_module"],
537  index["eta_module"],
538  0);
539  break;
540  case 2:
541  id = pixelIdHelper->wafer_id(index["barrel_endcap"],
542  index["layer_wheel"],
543  0,
544  0,
545  0);
546  break;
547  case 3:
548  id = pixelIdHelper->wafer_id(index["barrel_endcap"],
549  0,
550  0,
551  0,
552  0);
553  break;
554  default:
555  throw GaudiException("Unknown level " + std::to_string(level) + " for alignment in addAlignable",
556  "PixelGmxInterface::addAlignable", StatusCode::FAILURE);
557  break;
558  }
560 }
561 
562 
563 } // namespace ITk
564 } // 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:513
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:448
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:227
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:273
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:204
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