ATLAS Offline Software
Loading...
Searching...
No Matches
PixelGmxInterface.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
5
16
20#include <GeoModelRead/ReadGeoModel.h>
21#include <GeoModelKernel/GeoFullPhysVol.h>
22
23namespace
24{
25constexpr int PixelHitIndex{0};
26
27InDetDD::PixelReadoutTechnology getPixelReadoutTechnology(InDetDD::DetectorType detectorType, int rowsPerCircuit, int columnsPerCircuit) {
28 if (detectorType == InDetDD::DetectorType::PixelBarrel
29 || detectorType == InDetDD::DetectorType::PixelEndcap
31 || detectorType == InDetDD::DetectorType::PLR) {
32 // if ITk
34 }
35 else {
36 // if not ITk
37 if (rowsPerCircuit*columnsPerCircuit>26000) { return InDetDD::PixelReadoutTechnology::FEI4; }
39 }
40}
41}
42
43
44namespace InDetDD
45{
46
47namespace ITk
48{
49
51 SiCommonItems *commonItems,
52 WaferTree *moduleTree)
53 : AthMessaging("PixelGmxInterface"),
54 m_detectorManager(detectorManager),
55 m_commonItems(commonItems),
56 m_moduleTree(moduleTree)
57{}
58
59
60int PixelGmxInterface::sensorId(std::map<std::string, int> &index) const
61{
62 // Return the Simulation HitID (nothing to do with "ATLAS Identifiers" aka "Offline Identifiers")
63
64 // Check if identifier is valid
65 // TODO: drop this check in the future
66 const PixelID *pixelIdHelper = dynamic_cast<const PixelID *>(m_commonItems->getIdHelper());
67 if (not pixelIdHelper){
68 ATH_MSG_ERROR("Failed dynamic_cast to PixelID in PixelGmxInterface::sensorId");
69 return -1;
70 }
71 Identifier id = pixelIdHelper->wafer_id(index["barrel_endcap"],
72 index["layer_wheel"],
73 index["phi_module"],
74 index["eta_module"]);
75 IdentifierHash hashId = pixelIdHelper->wafer_hash(id);
76 if (!hashId.is_valid()) {
77 ATH_MSG_WARNING("Invalid hash for Index list: " << index["barrel_endcap"] << " " << index["layer_wheel"] << " "
78 << index["eta_module"] << " " << index["phi_module"] << " " << index["side"]);
79 return -1;
80 }
81
82 // Compute the actuall SiHitId
83 int hitIdOfModule = SiHitIdHelper::GetHelper()->buildHitId(PixelHitIndex,
84 index["barrel_endcap"],
85 index["layer_wheel"],
86 index["eta_module"],
87 index["phi_module"],
88 index["side"]);
89
90 ATH_MSG_DEBUG("Index list: " << index["barrel_endcap"] << " " << index["layer_wheel"] << " "
91 << index["eta_module"] << " " << index["phi_module"] << " " << index["side"]);
92 ATH_MSG_DEBUG("hitIdOfModule = " << std::hex << hitIdOfModule << std::dec);
93 ATH_MSG_DEBUG(" bec = " << SiHitIdHelper::GetHelper()->getBarrelEndcap(hitIdOfModule)
94 << " lay = " << SiHitIdHelper::GetHelper()->getLayerDisk(hitIdOfModule)
95 << " eta = " << SiHitIdHelper::GetHelper()->getEtaModule(hitIdOfModule)
96 << " phi = " << SiHitIdHelper::GetHelper()->getPhiModule(hitIdOfModule)
97 << " side = " << SiHitIdHelper::GetHelper()->getSide(hitIdOfModule));
98
99 return hitIdOfModule;
100}
101
102
103void PixelGmxInterface::addSensorType(const std::string& clas,
104 const std::string& typeName,
105 const std::map<std::string, std::string>& parameters)
106{
107 ATH_MSG_DEBUG("addSensorType called for class " << clas << ", typeName " << typeName);
108
109 if (clas == "SingleChip_RD53" || clas == "QuadChip_RD53") {
110 makePixelModule(typeName, parameters);
111 // @TODO remove once all endcap modules are oriented consistently i.e. there is
112 // one relation between local "hardware" coordinates and local offline coordinates.
113 // Currently all endcap modules have a surface normal (defined by the transform),
114 // which points outwards. This is the case for endcap modules for which the sensor
115 // facing side points towards the IP (even phi index), and those for which the sensor
116 // facing side points outwards (odd phi index). By introducing separate module design
117 // objects for endcap modules with even or odd phi index, the module design can
118 // provide extra information to indicate the translation scheme between hardware
119 // coordinates and offline coordinates.
120 if ( typeName.find("Quad")!= std::string::npos
121 && ( typeName.find("endcap")!= std::string::npos
122 || typeName.find("inclined")!= std::string::npos)) {
123 makePixelModule(typeName+"_even",parameters);
124 }
125 } else {
126 ATH_MSG_ERROR("addSensorType: unrecognised module class: " << clas);
127 ATH_MSG_ERROR("No module design created");
128 }
129}
130
131
132void PixelGmxInterface::makePixelModule(const std::string &typeName,
133 const std::map<std::string, std::string> &parameters)
134{
135 int circuitsPerEta{2}; // row
136 int circuitsPerPhi{2}; // column
137 double thickness{0.150};
138 double pitchEta{};
139 double pitchPhi{};
140 double pitchEtaLong{};
141 double pitchPhiLong{};
142 double pitchEtaEnd{};
143 double pitchPhiEnd{};
144 int nEtaLongPerSide{};
145 int nPhiLongPerSide{};
146 int nEtaEndPerSide{};
147 int nPhiEndPerSide{};
148 int rowsPerCircuit{};
149 int columnsPerCircuit{};
150
151 // unused
153 int readoutSide{1};
154 bool is3D{false};
155
156 bool phiSymmetric{true};
157 bool etaSymmetric{true};
158 bool depthSymmetric{true};
159
160 // read parameters
161 getParameter(typeName, parameters, "circuitsPerEta", circuitsPerEta);
162 getParameter(typeName, parameters, "circuitsPerPhi", circuitsPerPhi);
163 getParameter(typeName, parameters, "thickness", thickness);
164 getParameter(typeName, parameters, "is3D", is3D);
165 getParameter(typeName, parameters, "rows", rowsPerCircuit);
166 getParameter(typeName, parameters, "columns", columnsPerCircuit);
167 getParameter(typeName, parameters, "pitchEta", pitchEta);
168 getParameter(typeName, parameters, "pitchPhi", pitchPhi);
169 getParameter(typeName, parameters, "pitchEtaLong", pitchEtaLong);
170 getParameter(typeName, parameters, "pitchPhiLong", pitchPhiLong);
171 getParameter(typeName, parameters, "pitchEtaEnd", pitchEtaEnd);
172 getParameter(typeName, parameters, "pitchPhiEnd", pitchPhiEnd);
173 getParameter(typeName, parameters, "nPhiLongPerSide", nPhiLongPerSide);
174 getParameter(typeName, parameters, "nEtaLongPerSide", nEtaLongPerSide);
175 getParameter(typeName, parameters, "nPhiEndPerSide", nPhiEndPerSide);
176 getParameter(typeName, parameters, "nEtaEndPerSide", nEtaEndPerSide);
177
178 checkParameter(typeName, parameters, "phiSymmetric", phiSymmetric);
179 checkParameter(typeName, parameters, "etaSymmetric", etaSymmetric);
180 checkParameter(typeName, parameters, "depthSymmetric", depthSymmetric);
181
182 //
183 // Make Module Design and add to DetectorManager
184 //
185 ATH_MSG_DEBUG("readout geo - design thickness " << thickness << " "
186 << " circuits " << circuitsPerPhi << " " << circuitsPerEta << " "
187 << " rows/columns " << rowsPerCircuit << " " << columnsPerCircuit << " "
188 << " pitch regular/long/end " << pitchPhi << " " << pitchEta
189 << " " << pitchPhiLong << " " << pitchEtaLong
190 << " " << pitchPhiEnd << " " << pitchEtaEnd
191 << " n-long " << nPhiLongPerSide << " " << nEtaLongPerSide
192 << " n-end " << nPhiEndPerSide << " " << nEtaEndPerSide
193 << carrier << " " << readoutSide);
194
195 //For optionally setting PixelBarrel,PixelEndcap,PixelInclined
196 //(so far) primarily useful for the latter to avoid orientation warnings
197 InDetDD::DetectorType detectorType{InDetDD::PixelBarrel}; // TODO: we should probably fail and not default to barrel here.
198 int detectorTypeEnum = 0;
199 if (checkParameter(typeName, parameters, "detectorType", detectorTypeEnum)) {
200 if (detectorTypeEnum == 1) detectorType = InDetDD::PixelBarrel;
201 else if (detectorTypeEnum == 2) detectorType = InDetDD::PixelEndcap;
202 else if (detectorTypeEnum == 3) detectorType = InDetDD::PixelInclined;
203 }
204
205 InDetDD::PixelReadoutTechnology readoutTechnology = getPixelReadoutTechnology(detectorType, rowsPerCircuit, columnsPerCircuit );
206
207 if ( circuitsPerPhi*rowsPerCircuit<0 || circuitsPerPhi*rowsPerCircuit >= std::numeric_limits<PixelDiodeTree::CellIndexType>::max()
208 || circuitsPerEta*columnsPerCircuit<0 || circuitsPerEta*columnsPerCircuit >= std::numeric_limits<PixelDiodeTree::CellIndexType>::max()) {
209 std::stringstream amsg;
210 amsg << "Index overflows index type of PixelDiodeTree. Parameters "
211 << "( " << circuitsPerPhi << " * " << rowsPerCircuit << " ), ( "
212 << "( " << circuitsPerEta << " * " << columnsPerCircuit << " ) !<"
213 << std::numeric_limits<PixelDiodeTree::CellIndexType>::max() << " each.";
214 throw std::runtime_error(amsg.str());
215 }
216
217 // @TODO remove once all endcap modules are oriented consistently i.e. there is
218 // one relation between local "hardware" coordinates and local offline coordinates
219 bool flipFE=(typeName.find("_even") !=std::string::npos);
220
221 // helper function to associate correct diode type and front-end number to sub-matrices and diodes
222 // in the diode tree as attributes.
223 auto computeAttribute = [readoutTechnology,
224 pitchPhi,
225 pitchEta,
226 circuitsPerPhi,
227 circuitsPerEta,
228 rowsPerCircuit,
229 columnsPerCircuit,
230 flipFE
231 ](const std::array<PixelDiodeTree::IndexType,2> &split_idx,
232 const PixelDiodeTree::Vector2D &diode_width,
233 [[maybe_unused]] const std::array<bool,4> &ganged,
234 [[maybe_unused]] unsigned int split_i,
235 PixelDiodeTree::AttributeType current_matrix_attribute,
236 PixelDiodeTree::AttributeType current_diode_attribute)
237 -> std::tuple<PixelDiodeTree::AttributeType,PixelDiodeTree::AttributeType>
238 {
239 // split_idx the absolute index at which this sub-matrix is split into 4 sub-sub-matrices
240 // diode_width the diode pitch in both directions
241 // ganged ganged[0],ganged[1] whether the pixel diode is ganged in the corresponding direction
242 // ganged[2],ganged[3] whether the diode is inside (true) or outside the dead zone
243 // where ganged[2] denotes the flag in local-x and ganged[3] in local-y direction
244 //
245 // split_i defines which of the 4 areas the diode belongs to : 2 | 3 ^
246 // ----- | local-y (chip-columns)
247 // 0 | 1 |
248 // ---> local-x (chip-rows)
249 //
250 // current_matrix_attribute the default attribute for the unsplit sub-matrix assigned by the builder
251 // current_diode_attribute the default attribute assigned to the current diode associated to the split
252 // area specified by split_i
253 // return new matrix attribute, new diode attribute
254
255 // if the pixel is significantly wider in one direction consider the pixel to be long
256 // or if wider in both directions large
257 assert(split_idx[0]>=0 && split_idx[1]>=0);
258 std::array<int,2> chip_idx{split_idx[0]/rowsPerCircuit, split_idx[1]/columnsPerCircuit};
259
260 unsigned int n_large_dimensions = ( (std::abs(diode_width[0]-pitchPhi)>pitchPhi*.25)
261 +(std::abs(diode_width[1]-pitchEta)>pitchEta*.25));
262 switch (n_large_dimensions) {
263 case 1:
265 break;
266 case 2:
268 break;
269 default:
271 }
272
273 if (readoutTechnology==InDetDD::PixelReadoutTechnology::RD53) {
274 // The matrix attribute is used to store the front-end number, this works because
275 // the matrices are first split by circuit and then by inner edge.
276
277 // @TODO Is the numbering-scheme something that should be specified by the DB ?
278 //
279 // The front-ends are numbered like ^ 0 | 1 2 | 3
280 // | ----- ------
281 // local-x | 2 | 3 0 \ 1
282 // row/phi | (even) (odd)
283 // + ---> local-y (chip-column/eta)
284 //
285 // (the sensor facing side of even modules points towards the IP)
286
287 // Numbering scheme taken from the ITkPixelReadoutManager:
288 if (flipFE) {
289 current_matrix_attribute = InDetDD::detail::makeAttributeType(chip_idx[1] + (circuitsPerPhi-chip_idx[0]-1)*2);
290 }
291 else {
292 current_matrix_attribute = InDetDD::detail::makeAttributeType(chip_idx[1] + chip_idx[0]*2);
293 }
294
295 }
296 else {
297 // @TODO compute front-end number correctly
298 // just do something simple:
299 // if there is a single row just the chip-column (local-y, eta)
300 // if there are two rows: top row chip-column starting from the opposite end; bottom row: chip column + chips per top row
301 // ^ 0 |.. |n/2-1
302 // local-x | --------------- [swapped axis direction to fit into fewer lines]
303 // /eta | n-1 |... |n/2
304 // --> local-y (chip-rows, phi)
305 current_matrix_attribute = InDetDD::detail::makeAttributeType( chip_idx[0] > 0
306 ? circuitsPerEta - chip_idx[1] - 1
307 : (circuitsPerPhi-1) * circuitsPerEta + chip_idx[1]);
308 }
309 return std::make_tuple(current_matrix_attribute, current_diode_attribute);
310 };
311
312 PixelDiodeTree diode_tree
313 = createPixelDiodeTree(std::array<unsigned int,2>{static_cast<unsigned int>(circuitsPerPhi),static_cast<unsigned int>(circuitsPerEta)},
314 std::array<unsigned int,2>{static_cast<unsigned int>(rowsPerCircuit),static_cast<unsigned int>(columnsPerCircuit)},
315 PixelDiodeTree::Vector2D{pitchPhi,pitchEta}, // regular ptich
316 std::array<std::array<unsigned int,2>, 2>{ std::array<unsigned int,2>{static_cast<unsigned int>(nPhiEndPerSide),
317 static_cast<unsigned int>(nEtaEndPerSide)}, // outer edge in pixels
318 std::array<unsigned int,2>{static_cast<unsigned int>(nPhiLongPerSide),
319 static_cast<unsigned int>(nEtaLongPerSide)}}, // inner edge in pixels
320 std::array<PixelDiodeTree::Vector2D,2>{PixelDiodeTree::Vector2D{pitchPhiEnd, pitchEtaEnd}, // outer edge pitch (correct?)
321 PixelDiodeTree::Vector2D{pitchPhiLong,pitchEtaLong} // inner edge pitch
322 },
323 std::array<std::array<unsigned int,2>, 2>{ std::array<unsigned int,2>{0u,0u}, // @TODO add dead zone for run1-3 pixels?
324 std::array<unsigned int,2>{0u,0u} // @TODO add dead zone for run1-3 pixels?
325 },
326 computeAttribute,
327 nullptr);
328
329 auto design = std::make_unique<PixelModuleDesign>(thickness,
330 phiSymmetric, etaSymmetric, depthSymmetric,
331 circuitsPerPhi, circuitsPerEta,
332 columnsPerCircuit, rowsPerCircuit,
333 columnsPerCircuit, rowsPerCircuit,
334 std::move(diode_tree), carrier,
335 readoutSide, is3D, detectorType, readoutTechnology);
336
337 ATH_MSG_DEBUG("readout geo - design : " << typeName
338 << " " << design->width() << "x" << design->length() << "x" << design->thickness()
339 << " " << design->rows() << "x" << design->columns()
340 << ", " << circuitsPerPhi << "x" << circuitsPerEta << " "
341 << rowsPerCircuit << " " << columnsPerCircuit << ":\n"
342 << diode_tree.debugStringRepr());
343
344 [[maybe_unused]] auto observePtr = m_detectorManager->addDesign(std::move(design));
345
346 // Add to map for addModule routine
347 m_geometryMap[typeName] = m_detectorManager->numDesigns() - 1;
348}
349
350
351void PixelGmxInterface::addSensor(const std::string& typeName,
352 std::map<std::string, int> &index,
353 int /*sensitiveId*/,
354 GeoVFullPhysVol *fpv)
355{
356 //
357 // Get the ATLAS "Offline" wafer identifier
358 //
359 const PixelID *pixelIdHelper = dynamic_cast<const PixelID *>(m_commonItems->getIdHelper());
360 if (not pixelIdHelper){
361 ATH_MSG_ERROR("Failed dynamic_cast to PixelID in PixelGmxInterface::addSensor");
362 return;
363 }
364 Identifier id = pixelIdHelper->wafer_id(index["barrel_endcap"],
365 index["layer_wheel"],
366 index["phi_module"],
367 index["eta_module"]);
368 IdentifierHash hashId = pixelIdHelper->wafer_hash(id);
369 //
370 // Now do our best to check if this is a valid id. If either the gmx file is wrong, or the xml file
371 // defining the allowed id's is wrong, you can get disallowed id's. These cause a crash later
372 // if allowed through. To do the check, we ask for the hash-id of this id. Invalid ids give a
373 // special invalid hash-id (0xFFFFFFFF). But we don't exit the run, to help debug things quicker.
374 //
375 if (!hashId.is_valid()) {
376 ATH_MSG_ERROR("Invalid id for sensitive module " << typeName << " volume with indices");
377 for (const auto& [key, value] : index) {
378 msg() << MSG::ERROR << key << " = " << value << "; ";
379 }
380 msg() << MSG::ERROR << endmsg;
381 ATH_MSG_ERROR("Refusing to make it into a sensitive element. Incompatible gmx and identifier-xml files.");
382 return;
383 }
384
385 // @TODO remove once all endcap modules are oriented consistently i.e. there is
386 // one relation between local "hardware" coordinates and local offline coordinates
387 // Currently all endcap modules have a surface normal (defined by the transform),
388 // which points outwards. This is the case for endcap modules for which the sensor
389 // facing side points towards the IP (even phi index), and those for which the sensor
390 // facing side points outwards (odd phi index). By introducing separate module design
391 // objects for endcap modules with even or odd phi index, the module design can
392 // provide extra information to indicate the translation scheme between hardware
393 // coordinates and offline coordinates.
394 bool flipFE=index["barrel_endcap"]!=0 && index["phi_module"]%2==0 && typeName.find("Quad") != std::string::npos;
395 //
396 // Create the detector element and add to the DetectorManager
397 //
398 auto it = m_geometryMap.find( (flipFE ? typeName+"_even" : typeName));
399 if(it == m_geometryMap.end()) {
400 ATH_MSG_ERROR("addSensor: Error: Readout sensor type " << typeName << " not found.");
401 throw std::runtime_error("readout sensor type " + typeName + " not found.");
402 }
403 const SiDetectorDesign *design = m_detectorManager->getDesign(it->second);
404 ATH_MSG_VERBOSE("Adding sensor with design: " << typeName << " " << design);
405 if (design == nullptr) {
406 ATH_MSG_ERROR("addSensor: Error: Readout sensor type " << typeName << " not found.");
407 throw std::runtime_error("readout sensor type " + typeName + " not found.");
408 }
409
410 m_detectorManager->addDetectorElement(new SiDetectorElement(id, design, fpv, m_commonItems));
411
412 //
413 // Build up a map-structure for numerology
414 //
415 Wafer module((unsigned int) hashId);
416 std::string errorMessage("");
417 if (!m_moduleTree->add(index["barrel_endcap"],
418 index["layer_wheel"],
419 index["eta_module"],
420 index["phi_module"],
421 module,
422 errorMessage)) {
423 ATH_MSG_ERROR(errorMessage);
424 }
425
426 return;
427}
428
429void PixelGmxInterface::buildReadoutGeometryFromSqlite(IRDBAccessSvc * rdbAccessSvc,GeoModelIO::ReadGeoModel* sqlreader){
430
431 const std::array<std::string,2> sensorTypes{"QuadChip_RD53","SingleChip_RD53"};
432 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"};
433
434 for(const std::string & sType:sensorTypes){
435 IRDBRecordset_ptr rd53 = rdbAccessSvc->getRecordsetPtr(sType,"");
436 if(rd53->size() !=0){
437 for (unsigned int iR =0;iR<rd53->size();iR++){
438 std::map<std::string,std::string> rd53_Map;
439 for(const std::string & paramName:rd53_ParamNames){
440 std::string paramValue = (*rd53)[iR]->getString(paramName);
441 rd53_Map[paramName] = std::move(paramValue);
442 }
443 std::string rd35_Name = (*rd53)[iR]->getString("SensorType");
444 makePixelModule(rd35_Name,rd53_Map);
445 // @TODO remove once all endcap modules are oriented consistently i.e. there is
446 // one relation between local "hardware" coordinates and local offline coordinates
447 if ( rd35_Name.find("Quad")!= std::string::npos
448 && ( rd35_Name.find("endcap")!= std::string::npos
449 || rd35_Name.find("inclined")!= std::string::npos)) {
450 makePixelModule(rd35_Name+"_even",rd53_Map);
451 }
452 }
453 }
454 else ATH_MSG_WARNING("Could not retrieve "<<sType<<" table");
455 }
456
457 //Now, loop over the FullPhysVols and create the SiDetectorElements
458 //lots of string parsing...
459 const std::array<std::string,5> fields{"barrel_endcap","layer_wheel","phi_module","eta_module","side"};
460 //First, find which name the tables are in the file under (depends upon the plugin used to create the input file)
461 //sort these in order of precedence - ITkPlugin, then ITkPixelPlugin, then GeoModelXMLPlugin
462 const std::array<std::string,3> publishers({"ITk","ITkPixel","GeoModelXML"});
463 //The below is a map of string keys which will contain all the Identifier/DetElement relevant info, and the associated FullPhysVol
464 // (once filled from the published table in the SQLite)
465 std::map<std::string, GeoFullPhysVol*> mapFPV;
466 for (auto & iPub : publishers){
467 //setting the "checkTable" option to true, so that an empty map will be returned if not found and we can try the next one
468 mapFPV = sqlreader->getPublishedNodes<std::string, GeoFullPhysVol*>(iPub,true);
469 if (!mapFPV.empty()) {
470 ATH_MSG_DEBUG("Using FPV tables from publisher "<<iPub);
471 break;
472 }
473 }
474 if (mapFPV.empty()) ATH_MSG_ERROR("Could not find any FPV tables under the expected names: "<<publishers);
475
476 for (const auto&[fullPhysVolInfoString, fullPhysVolPointer] : mapFPV){
477 //find the name of the corresponding detector design type
478 size_t startRG = fullPhysVolInfoString.find("RD53_");
479 if(startRG==std::string::npos){
480 ATH_MSG_DEBUG("GeoFullPhysVol "<<fullPhysVolInfoString<<" does not have the expected format. Skipping");
481 continue;
482 }
483 std::string typeName = fullPhysVolInfoString.substr(startRG);
484 std::map<std::string, int> index;
485 for (const std::string & field:fields){
486 size_t first = fullPhysVolInfoString.find(field+"_");
487 size_t last = fullPhysVolInfoString.find('_',first+field.size()+1);//start looking only after end of first delimiter (plus 1 for the "_" appended) ends
488 if(first==std::string::npos || last==std::string::npos){
489 ATH_MSG_DEBUG("Could not extract "<<field<<" from "<<fullPhysVolInfoString<<". Skipping");
490 continue;
491 }
492 std::string strNew = fullPhysVolInfoString.substr(first+field.size()+1,last-(first+field.size()+1));
493 index[field] = std::stoi(strNew);
494 }
495
496 addSensor(typeName,index,0,fullPhysVolPointer);
497 }
498
499}
500
502 std::map<std::string, int> &index,
503 GeoVFullPhysVol *fpv,
504 GeoAlignableTransform *transform)
505{
506 ATH_MSG_DEBUG("addAlignable called");
507 const PixelID *pixelIdHelper = dynamic_cast<const PixelID *> (m_commonItems->getIdHelper());
508 if (not pixelIdHelper){
509 ATH_MSG_ERROR("Dynamic cast to PixelID failed in PixelGmxInterface::addAlignable");
510 return;
511 }
512 Identifier id;
513 switch (level) {
514 case 0:
515 id = pixelIdHelper->wafer_id(index["barrel_endcap"],
516 index["layer_wheel"],
517 index["phi_module"],
518 index["eta_module"],
519 index["side"]);
520 break;
521 case 1:
522 id = pixelIdHelper->wafer_id(index["barrel_endcap"],
523 index["layer_wheel"],
524 index["phi_module"],
525 index["eta_module"],
526 0);
527 break;
528 case 2:
529 id = pixelIdHelper->wafer_id(index["barrel_endcap"],
530 index["layer_wheel"],
531 0,
532 0,
533 0);
534 break;
535 case 3:
536 id = pixelIdHelper->wafer_id(index["barrel_endcap"],
537 0,
538 0,
539 0,
540 0);
541 break;
542 default:
543 throw GaudiException("Unknown level " + std::to_string(level) + " for alignment in addAlignable",
544 "PixelGmxInterface::addAlignable", StatusCode::FAILURE);
545 break;
546 }
547 m_detectorManager->addAlignableTransform(level, id, transform, fpv);
548}
549
550
551} // namespace ITk
552} // namespace InDetDD
#define endmsg
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Definition of the abstract IRDBAccessSvc interface.
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition of the abstract IRDBRecord interface.
Definition of the abstract IRDBRecordset interface.
MsgStream & msg() const
The standard message stream.
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
IRDBAccessSvc is an abstract interface to the athena service that provides the following functionalit...
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.
virtual unsigned int size() const =0
This is a "hash" representation of an Identifier.
bool is_valid() const
Check if id is in a valid state.
virtual void addSensorType(const std::string &clas, const std::string &typeName, const std::map< std::string, std::string > &parameters) override
virtual void addAlignable(int level, std::map< std::string, int > &index, GeoVFullPhysVol *fpv, GeoAlignableTransform *transform) override final
void makePixelModule(const std::string &typeName, const std::map< std::string, std::string > &parameters)
PixelDetectorManager * m_detectorManager
PixelGmxInterface(PixelDetectorManager *detectorManager, SiCommonItems *commonItems, WaferTree *moduleTree)
virtual void addSensor(const std::string &typeName, std::map< std::string, int > &index, int sequentialId, GeoVFullPhysVol *fpv) override
void buildReadoutGeometryFromSqlite(IRDBAccessSvc *rdbAccessSvc, GeoModelIO::ReadGeoModel *sqlreader)
std::map< std::string, int > m_geometryMap
virtual int sensorId(std::map< std::string, int > &index) const override
Dedicated detector manager extending the functionality of the SiDetectorManager with dedicated pixel ...
Tree structure to find the position, index or pitch of a pixel on a semi-regular grid The grid is con...
std::string debugStringRepr() const
Dump the diode tree structure into a string.
Helper class to concentrate common items, such as the pointer to the IdHelper, the lorentzAngle tool ...
Base class for the detector design classes for Pixel and SCT.
Class to hold geometrical description of a silicon detector element.
This is an Identifier helper class for the Pixel subdetector.
Definition PixelID.h:67
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module) const
For a single crystal.
Definition PixelID.h:360
IdentifierHash wafer_hash(Identifier wafer_id) const
wafer hash from id
Definition PixelID.h:383
int buildHitId(const int, const int, const int, const int, const int, const int) const
static const SiHitIdHelper * GetHelper()
InDetDD::PixelDiodeTree::AttributeType makeAttributeType(T val)
convenience method to convert the given value into an attribute
Message Stream Member.
PixelDiodeTree createPixelDiodeTree(const std::array< unsigned int, 2 > &chip_dim, const std::array< unsigned int, 2 > &chip_matrix_dim, const PixelDiodeTree::Vector2D &pitch, const std::array< std::array< unsigned int, 2 >, 2 > &edge_dim, const std::array< PixelDiodeTree::Vector2D, 2 > &edge_pitch, const std::array< std::array< unsigned int, 2 >, 2 > &dead_zone, const AttributeRefiner &func_compute_attribute, std::ostream *debug_out=nullptr)
Create a pixel diode tree.
Definition index.py:1