ATLAS Offline Software
Loading...
Searching...
No Matches
ReadSiDetectorElements.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include "CLHEP/Units/SystemOfUnits.h"
8
17#include "Identifier/Identifier.h"
18
20
21#include <string>
22
23using namespace InDetDD;
24
25
27//
28// Prints out SiDetectorElement positions and other info.
29
31
32ReadSiDetectorElements::ReadSiDetectorElements(const std::string& name, ISvcLocator* pSvcLocator) :
33 AthAlgorithm(name, pSvcLocator){
34 // Get parameter values from jobOptions file
35 declareProperty("ManagerName", m_managerName);
36 declareProperty("LoopOverElements", m_doLoop);
37 declareProperty("DoInitialize", m_doInit = false);
38 declareProperty("DoExecute", m_doExec = true);
39 declareProperty("UseConditionsTools", m_useConditionsTools = false);
40 declareProperty("PrintProbePositions", m_printProbePositions = true);
41 declareProperty("PrintTransforms", m_printTransforms = true);
42 declareProperty("PrintDirections", m_printDirections = true);
43}
44
45// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
46
48 // Retrieve GeoModel Detector Elements
49 // You can either get the SCT or pixel manager or the common base class
50 // manager. In this example I get the base class.
51 // const SiDetectorManager * manager;
52 // or
53 // const PixelDetectorManager * manager;
54 // const SCT_DetectorManager * manager;
55
57 if (m_managerName == "Pixel" || m_managerName == "ITkPixel") {
58 //
59 // Get Pixel ID helper
60 //
61 // Pixel ID helper: const PixelID * m_pixelIdHelper;
62 ATH_CHECK(detStore()->retrieve(m_pixelIdHelper, "PixelID"));
63 // If common pixel/SCT code can copy to pointer to AtlasDetectorID
65 } else {
66 //
67 // Get SCT ID helper
68 //
69 // SCT ID helper: const SCT_ID * m_sctIdHelper;
70 ATH_CHECK(detStore()->retrieve(m_sctIdHelper, "SCT_ID"));
71 // If common pixel/SCT code can copy to pointer to AtlasDetectorID
73 }
74 //from now on, don't check the names, just whether the corresponding helper is valid
75
78 ATH_CHECK(m_siConditionsTool.retrieve());
79 } else {
80 m_siLorentzAngleTool.disable();
81 m_siConditionsTool.disable();
82 }
83
84 // Initialize ReadCondHandleKey
85 ATH_CHECK(m_detEleCollKey.initialize());
86
87 // Print during initialize
88 if (m_doInit) {
89 printAllElements(true);
91 }
92 return StatusCode::SUCCESS;
93}
94
95
96StatusCode ReadSiDetectorElements::execute(const EventContext& /*ctx*/) {
97 // Only print out on first event
98 if (m_first && m_doExec) {
99 m_first = false;
100 printAllElements(false);
101 printRandomAccess(false);
103 }
104 return StatusCode::SUCCESS;
105}
106
107void ReadSiDetectorElements::printAllElements(const bool accessDuringInitialization) {
108 const bool useConditionStore = not accessDuringInitialization;
109 const SiDetectorElementCollection* elements = nullptr;
110 if (useConditionStore) {
111 // Get SiDetectorElementCollection from ConditionStore
113 elements = detEle.retrieve();
114 ATH_MSG_INFO("Going to read from Conditions Store using handle: " << m_detEleCollKey.key());
115 if (elements==nullptr) {
116 ATH_MSG_FATAL(m_detEleCollKey.fullKey() << " could not be retrieved");
117 return;
118 }
119 } else {
120 ATH_MSG_INFO("Going to read from detector manager: " << m_managerName);
121 elements = m_manager->getDetectorElementCollection();
122 }
123
124 // There are various ways you can access the elements. eg
125 // m_manager->getDetectorElement(idHash);
126 // m_manager->getDetectorElement(identifier);
127 //
128 // or access the whole collection or the iterators.
129 if (m_doLoop) {
130 for (const SiDetectorElement* element: *elements) {
131 if (!element) continue;
132 ATH_MSG_ALWAYS(m_idHelper->show_to_string(element->identify()));
133 // The id helper is also available through the elements
134 //
135 // element->getIdHelper()->show(element->identify());
136 //
137 ATH_MSG_ALWAYS(" center (x,y,z) = " << element->center().x() << "," << element->center().y() << "," << element->center().z());
138 ATH_MSG_ALWAYS(" center (r,phi,z) = " << element->center().perp() << "," << element->center().phi() << "," <<element->center().z());
140 ATH_MSG_ALWAYS(" global (r,phi,z) position of (1,1) = " <<element->globalPosition(Amg::Vector2D(1,1)).perp() << "," << element->globalPosition(Amg::Vector2D(1,1)).phi() <<","<< element->globalPosition(Amg::Vector2D(1,1)).z());
141 ATH_MSG_ALWAYS(" global (r,phi,z) position of (-1,-1) = " <<element->globalPosition(Amg::Vector2D(-1,-1)).perp() << "," << element->globalPosition(Amg::Vector2D(-1,-1)).phi() <<","<< element->globalPosition(Amg::Vector2D(-1,-1)).z());
142 ATH_MSG_ALWAYS(" global (r,phi,z) hit position of (1,1,0) = " <<element->globalPositionHit(Amg::Vector3D(1,1,0)).perp() << "," << element->globalPositionHit(Amg::Vector3D(1,1,0)).phi() <<","<< element->globalPositionHit(Amg::Vector3D(1,1,0)).z());
143 ATH_MSG_ALWAYS(" global (r,phi,z) hit position of (-1,-1,0) = " <<element->globalPositionHit(Amg::Vector3D(-1,-1,0)).perp() << "," << element->globalPositionHit(Amg::Vector3D(-1,-1,0)).phi() <<","<< element->globalPositionHit(Amg::Vector3D(-1,-1,0)).z());
144 ATH_MSG_ALWAYS(" Cell Id of (1,1) = " <<element->cellIdOfPosition(Amg::Vector2D(1,1)).etaIndex() << "," << element->cellIdOfPosition(Amg::Vector2D(1,1)).phiIndex());
145 ATH_MSG_ALWAYS(" Cell Id of (-1,-1) = " <<element->cellIdOfPosition(Amg::Vector2D(-1,-1)).etaIndex() << "," << element->cellIdOfPosition(Amg::Vector2D(-1,-1)).phiIndex());
146
147 }
148 ATH_MSG_ALWAYS(" Normal = " <<element->normal().perp() << "," << element->normal().phi() <<","<< element->normal().z());
149 ATH_MSG_ALWAYS(" sin(tilt), sin(stereo) = " << element->sinTilt() << " "
150 << element->sinStereo());
151 ATH_MSG_ALWAYS(" width, minWidth, maxWidth, length (mm) = "
152 << element->width()/CLHEP::mm << " "
153 << element->minWidth()/CLHEP::mm << " "
154 << element->maxWidth()/CLHEP::mm << " "
155 << element->length()/CLHEP::mm);
156
157 // These are no longer accessed through the detector element.
158 IdentifierHash hashId = element->identifyHash();
160 const EventContext &ctx = Gaudi::Hive::currentContext();
161 ATH_MSG_ALWAYS(" Temperature (C), bias voltage, depletion voltage: "
162 << m_siConditionsTool->temperature(hashId, ctx) << " "
163 << m_siConditionsTool->biasVoltage(hashId, ctx) << " "
164 << m_siConditionsTool->depletionVoltage(hashId, ctx));
165 ATH_MSG_ALWAYS(" Lorentz correction (mm), tanLorentzPhi = "
166 << m_siLorentzAngleTool->getLorentzShift(hashId, ctx)/CLHEP::mm << " "
167 << m_siLorentzAngleTool->getTanLorentzAngle(hashId, ctx));
168 }
169 ATH_MSG_ALWAYS(" HashId, Id : " << hashId << "\t" << element->identify().getString());
170 // Make some consistency tests for the identifier.
171 Identifier idTest;
172 IdentifierHash idHashTest;
173 if (m_pixelIdHelper) {
174 idTest = m_pixelIdHelper->wafer_id(hashId);
175 idHashTest = m_pixelIdHelper->wafer_hash(idTest);
176 } else if (m_sctIdHelper) {
177 idTest = m_sctIdHelper->wafer_id(hashId);
178 idHashTest = m_sctIdHelper->wafer_hash(idTest);
179 }
180 const SiDetectorElement * elementtest1 = nullptr;
181 const SiDetectorElement * elementtest2 = nullptr;
182 if (useConditionStore) {
183 // SiDetectorElementCollection::getDetectorElement supports only IdentifierHash as the argument.
184 if (m_pixelIdHelper) {
185 elementtest1 = elements->getDetectorElement(m_pixelIdHelper->wafer_hash(element->identify()));
186 } else if (m_sctIdHelper){
187 elementtest1 = elements->getDetectorElement(m_sctIdHelper->wafer_hash(element->identify()));
188 }
189 elementtest2 = elements->getDetectorElement(hashId);
190 } else {
191 elementtest1 = m_manager->getDetectorElement(element->identify());
192 elementtest2 = m_manager->getDetectorElement(hashId);
193 }
194 bool idOK = true;
195 if (idHashTest != hashId) {ATH_MSG_ALWAYS(" Id test 1 FAILED!"); idOK = false;}
196 if (idTest != element->identify()) {ATH_MSG_ALWAYS(" Id test 2 FAILED!"); idOK = false;}
197 if (elementtest1 != element) {ATH_MSG_ALWAYS(" Id test 3 FAILED!"); idOK = false;}
198 if (elementtest2 != element) {ATH_MSG_ALWAYS(" Id test 4 FAILED!"); idOK = false;}
199 if (idOK) ATH_MSG_ALWAYS(" ID tests OK") ;
201 const GeoTrf::Transform3D mytrf = element->transform();
202 const GeoTrf::Transform3D mytrfhit = element->transformHit();
203 ATH_MSG_ALWAYS("Transform: ");
204 ATH_MSG_ALWAYS("|"<<mytrf(2,0)<<","<<mytrf(2,1)<<","<<mytrf(2,2)<<"|");
205 ATH_MSG_ALWAYS("|"<<mytrf(1,0)<<","<<mytrf(1,1)<<","<<mytrf(1,2)<<"|");
206 ATH_MSG_ALWAYS("|"<<mytrf(0,0)<<","<<mytrf(0,1)<<","<<mytrf(0,2)<<"|");
207 ATH_MSG_ALWAYS("");
208 ATH_MSG_ALWAYS("TransformHit: ");
209 ATH_MSG_ALWAYS("|"<<mytrfhit(2,0)<<","<<mytrfhit(2,1)<<","<<mytrfhit(2,2)<<"|");
210 ATH_MSG_ALWAYS("|"<<mytrfhit(1,0)<<","<<mytrfhit(1,1)<<","<<mytrfhit(1,2)<<"|");
211 ATH_MSG_ALWAYS("|"<<mytrfhit(0,0)<<","<<mytrfhit(0,1)<<","<<mytrfhit(0,2)<<"|");
212 ATH_MSG_ALWAYS("");
213 }
215 ATH_MSG_ALWAYS("Depth Angle: "<<element->depthAngle());
216 if(element->depthDirection()) ATH_MSG_ALWAYS("Depth Direction True");
217 else ATH_MSG_ALWAYS("Depth Direction False");
218 ATH_MSG_ALWAYS("Eta Angle: "<<element->etaAngle());
219 if(element->etaDirection()) ATH_MSG_ALWAYS("Eta Direction True");
220 else ATH_MSG_ALWAYS("Eta Direction False");
221 ATH_MSG_ALWAYS("Phi Angle: "<<element->phiAngle());
222 if(element->phiDirection()) ATH_MSG_ALWAYS("Phi Direction True");
223 else ATH_MSG_ALWAYS("Phi Direction False");
224
225 if(std::abs(element->depthAngle())<0.5) ATH_MSG_ALWAYS("BAD DEPTH DIRECTION!");
226 if(std::abs(element->etaAngle())<0.5) ATH_MSG_ALWAYS("BAD ETA DIRECTION!");
227 if(std::abs(element->phiAngle())<0.5) ATH_MSG_ALWAYS("BAD PHI DIRECTION!");
228 }
229 //add divider between elements for readability
230 ATH_MSG_ALWAYS("-----------------------------");
231 }
232 }
233 // Testing numerology
234 const SiNumerology siNumerology(m_manager->numerology());
235 int nSides = 1;
236 if (m_sctIdHelper) nSides = 2;
237 int barrelCount = 0;
238 int barrelCountError = 0;
239 // Barrel
240 for (int iBarrelIndex = 0; iBarrelIndex < siNumerology.numBarrels(); iBarrelIndex++) {
241 int iBarrel = siNumerology.barrelId(iBarrelIndex);
242 ATH_MSG_ALWAYS("Barrel: " << iBarrel);
243 ATH_MSG_ALWAYS(" Num layers: " << siNumerology.numLayers());
244 for (int iLayer = 0; iLayer < siNumerology.numLayers(); iLayer++) {
245 ATH_MSG_ALWAYS(" Layer: " << iLayer);
246 if (!siNumerology.useLayer(iLayer))ATH_MSG_ALWAYS(" Layer not present");
247 ATH_MSG_ALWAYS(" Num Modules in Phi: " << siNumerology.numPhiModulesForLayer(iLayer));
248 ATH_MSG_ALWAYS(" Num Modules in Eta: " << siNumerology.numEtaModulesForLayer(iLayer));
249 for (int iPhi = 0; iPhi < siNumerology.numPhiModulesForLayer(iLayer); iPhi++) {
250 for (int iEta = siNumerology.beginEtaModuleForLayer(iLayer); iEta < siNumerology.endEtaModuleForLayer(iLayer); iEta++) {
251 if (!iEta && siNumerology.skipEtaZeroForLayer(iLayer)) continue;
252 for (int iSide = 0; iSide < nSides; iSide++) {
253 Identifier id;
254 if (m_pixelIdHelper){
255 id = m_pixelIdHelper->wafer_id(iBarrel,iLayer,iPhi,iEta);
256 } else if (m_sctIdHelper){
257 id = m_sctIdHelper->wafer_id(iBarrel,iLayer,iPhi,iEta,iSide);
258 }
259 const SiDetectorElement * element = nullptr;
260 if (useConditionStore) {
261 // SiDetectorElementCollection::getDetectorElement supports only IdentifierHash as the argument.
262 if (m_pixelIdHelper) {
263 element = elements->getDetectorElement(m_pixelIdHelper->wafer_hash(id));
264 } else if (m_sctIdHelper){
265 element = elements->getDetectorElement(m_sctIdHelper->wafer_hash(id));
266 }
267 } else {
268 element = m_manager->getDetectorElement(id);
269 }
270 barrelCount++;
271 if (!element) {
272 barrelCountError++;
273 ATH_MSG_ALWAYS(" No element found for id: " << m_idHelper->show_to_string(id));
274 } else {
275 // For extra safety in case some strip modules do not have two sides (eg in future geometries) one could add.
276 if (!element->otherSide()) iSide++;
277 ATH_MSG_ALWAYS(" " << m_idHelper->show_to_string(id));
278 }
279 } // iSide
280 } // iEta
281 } //iPhi
282 } //iLayer
283 } // Barrel
284
285 int endcapCount = 0;
286 int endcapCountError = 0;
287 // Endcap
288 for (int iEndcapIndex = 0; iEndcapIndex < siNumerology.numEndcaps(); iEndcapIndex++) {
289 int iEndcap = siNumerology.endcapId(iEndcapIndex);
290 ATH_MSG_ALWAYS("Endcap: " << iEndcap);
291 ATH_MSG_ALWAYS(" Num disks: " << siNumerology.numDisks());
292 for (int iDisk = 0; iDisk < siNumerology.numDisks(); iDisk++) {
293 ATH_MSG_ALWAYS(" Disk: " << iDisk);
294 if (!siNumerology.useDisk(iDisk))ATH_MSG_ALWAYS(" Disk not present");
295 ATH_MSG_ALWAYS(" Num Rings: " << siNumerology.numRingsForDisk(iDisk));
296 for (int iEta = 0; iEta < siNumerology.numRingsForDisk(iDisk); iEta++) {
297 ATH_MSG_ALWAYS(" Ring: " << iEta);
298 ATH_MSG_ALWAYS(" Num Modules in Phi: " << siNumerology.numPhiModulesForDiskRing(iDisk,iEta));
299 for (int iPhi = 0; iPhi < siNumerology.numPhiModulesForDiskRing(iDisk,iEta); iPhi++) {
300 for (int iSide = 0; iSide < nSides; iSide++) {
301 Identifier id;
302 if (m_pixelIdHelper) {
303 id = m_pixelIdHelper->wafer_id(iEndcap,iDisk,iPhi,iEta);
304 } else if (m_sctIdHelper){
305 id = m_sctIdHelper->wafer_id(iEndcap,iDisk,iPhi,iEta,iSide);
306 }
307 const SiDetectorElement * element = m_manager->getDetectorElement(id);
308 endcapCount++;
309 if (!element) {
310 endcapCountError++;
311 ATH_MSG_ALWAYS(" No element found for id: " << m_idHelper->show_to_string(id));
312 } else {
313 // For extra safety in case some strip modules do not have two sides (eg in future geometries) one could add.
314 if (!element->otherSide()) iSide++;
315 ATH_MSG_ALWAYS(" " << m_idHelper->show_to_string(id));
316 }
317 } // iSide
318 } // iEta
319 } //iPhi
320 } //iDisk
321 } // Endcap;
322
323 ATH_MSG_ALWAYS("Number of barrel elements : " << barrelCount);
324 ATH_MSG_ALWAYS("Number not found : " << barrelCountError);
325 ATH_MSG_ALWAYS("Number of endcap elements : " << endcapCount);
326 ATH_MSG_ALWAYS("Number not found : " << endcapCountError);
327
328 // Maximums
329 ATH_MSG_ALWAYS("MaxNumBarrelEta: " << siNumerology.maxNumBarrelEta());
330 ATH_MSG_ALWAYS("MaxNumEndcapRings: " << siNumerology.maxNumEndcapRings());
331 ATH_MSG_ALWAYS("MaxNumStrips: " << siNumerology.maxNumStrips());
332 ATH_MSG_ALWAYS("MaxNumPhiCells: " << siNumerology.maxNumPhiCells());
333 ATH_MSG_ALWAYS("MaxNumEtaCells: " << siNumerology.maxNumEtaCells());
334
335 ATH_MSG_ALWAYS("Num Designs: " << m_manager->numDesigns());
336}
337
338
339void ReadSiDetectorElements::printRandomAccess(const bool accessDuringInitialization) {
340 ATH_MSG_INFO("printRandomAccess()");
341
342 const bool useConditionStore = (m_managerName == "SCT" and (not accessDuringInitialization));
343 const SiDetectorElementCollection* elements = nullptr;
344 if (useConditionStore) {
345 // Get SiDetectorElementCollection from ConditionStore
347 elements = detEle.retrieve();
348 if (elements==nullptr) {
349 ATH_MSG_FATAL(m_detEleCollKey.fullKey() << " could not be retrieved");
350 return;
351 }
352 }
353
354 // Some random access
355 if (m_pixelIdHelper) {
356 //const PixelID * idHelper = dynamic_cast<const PixelID *>(m_manager->getIdHelper());
357 const PixelID * idHelper = m_pixelIdHelper;
358 Identifier id;
359 std::vector<SiCellId> cellIds;
360 std::vector<Amg::Vector2D> positions;
361 // wafer_id(barrel_ec, layer_disk, phi_module, eta_module)
362 // A barrel element
363 ATH_MSG_ALWAYS("----------------------------------------------");
364 ATH_MSG_ALWAYS(" A Pixel Barrel element (non B-layer) " );
365 ATH_MSG_ALWAYS("----------------------------------------------");
366 id = idHelper->wafer_id(0,1,15,-3);
367 cellIds.emplace_back(32,8); // phi,eta
368 //add a range of cells from 151 to 175
369 for (int i(151);i != 176; ++i){
370 cellIds.emplace_back(i,8); // phi,eta
371 }
372 cellIds.emplace_back(-1,1); // phi,eta
373 cellIds.emplace_back(0,1); // phi,eta
374 cellIds.emplace_back(1,-1); // phi,eta
375 cellIds.emplace_back(1,0); // phi,eta
376 cellIds.emplace_back(327,1); // phi,eta
377 cellIds.emplace_back(328,1); // phi,eta
378 cellIds.emplace_back(1,143); // phi,eta
379 cellIds.emplace_back(1,144); // phi,eta
380 positions.emplace_back(12.727*CLHEP::mm, 4.534*CLHEP::mm); // eta,phi
381 testElement(id, cellIds, positions, elements);
382
383 // A barrel element (B-Layer)
384 ATH_MSG_ALWAYS("----------------------------------------------");
385 ATH_MSG_ALWAYS(" A Pixel Barrel element (B-layer) " );
386 ATH_MSG_ALWAYS("----------------------------------------------");
387 id = idHelper->wafer_id(0,0,7,-3);
388 cellIds.clear();
389 positions.clear();
390 cellIds.emplace_back(32,8); // phi,eta
391 positions.emplace_back(12.727*CLHEP::mm, 4.534*CLHEP::mm); // eta,phi
392 testElement(id, cellIds, positions, elements);
393
394 // An endcap element
395 ATH_MSG_ALWAYS("----------------------------------------------");
396 ATH_MSG_ALWAYS(" A Pixel Endcap element" );
397 ATH_MSG_ALWAYS("----------------------------------------------");
398 id = idHelper->wafer_id(2,2,13,0);
399 cellIds.emplace_back(182,75); // phi,eta
400 positions.emplace_back(0*CLHEP::mm, 0*CLHEP::mm); // eta,phi
401 positions.emplace_back(30.4*CLHEP::mm, 8.2*CLHEP::mm); // eta,phi - on edge
402 positions.emplace_back(12*CLHEP::mm, -8.15*CLHEP::mm); // eta,phi - near edge
403 positions.emplace_back(12*CLHEP::mm, -8.25*CLHEP::mm); // eta,phi - near edge
404 positions.emplace_back(12*CLHEP::mm, -8.35*CLHEP::mm); // eta,phi - outside
405 testElement(id, cellIds, positions, elements);
406
407
408 } else if (m_sctIdHelper) {
409 const SCT_ID * idHelper = m_sctIdHelper;
410 Identifier id;
411 std::vector<SiCellId> cellIds;
412 std::vector<Amg::Vector2D> positions;
413
414
415 // wafer_id(barrel_ec, layer_disk, phi_module, eta_module, side)
416 // A barrel element
417 ATH_MSG_ALWAYS("----------------------------------------------");
418 ATH_MSG_ALWAYS(" A SCT Barrel element" );
419 ATH_MSG_ALWAYS("----------------------------------------------");
420 id = idHelper->wafer_id(0,1,15,-3,0);
421 cellIds.clear();
422 positions.clear();
423 cellIds.emplace_back(32); // phi,eta
424 cellIds.emplace_back(1); // phi,eta
425 cellIds.emplace_back(0); // phi,eta
426 if (m_managerName == "SCT") {
427 cellIds.emplace_back(-1); // phi,eta
428 cellIds.emplace_back(-2); // phi,eta
429 cellIds.emplace_back(-3); // phi,eta
430 }
431 cellIds.emplace_back(767); // phi,eta
432 cellIds.emplace_back(768); // phi,eta
433 positions.emplace_back(12.727*CLHEP::mm, 4.534*CLHEP::mm); // eta,phi
434 testElement(id, cellIds, positions, elements);
435
436 // A barrel element (other side of above)
437 ATH_MSG_ALWAYS("----------------------------------------------");
438 ATH_MSG_ALWAYS(" A SCT Barrel element (other side of above) ");
439 ATH_MSG_ALWAYS("----------------------------------------------");
440 id = idHelper->wafer_id(0,1,15,-3,1);
441 cellIds.clear();
442 positions.clear();
443 cellIds.emplace_back(32); // phi,eta
444 positions.emplace_back(12.727*CLHEP::mm, 4.534*CLHEP::mm); // eta,phi
445 testElement(id, cellIds, positions, elements);
446
447 // A outer fwd
448 ATH_MSG_ALWAYS("----------------------------------------------");
449 ATH_MSG_ALWAYS(" A SCT Endcap element (outer type)" );
450 ATH_MSG_ALWAYS("----------------------------------------------");
451 id = idHelper->wafer_id(2,3,15,0,0);
452 cellIds.clear();
453 positions.clear();
454 cellIds.emplace_back(532); // phi,eta
455 cellIds.emplace_back(0); // phi,eta
456 if (m_managerName == "SCT") cellIds.emplace_back(-1); // phi,eta
457 cellIds.emplace_back(767); // phi,eta
458 cellIds.emplace_back(768); // phi,eta
459 positions.emplace_back(12.727*CLHEP::mm, 20.534*CLHEP::mm); // eta,phi
460 positions.emplace_back(12.727*CLHEP::mm, -20.534*CLHEP::mm); // eta,phi
461 positions.emplace_back(3*CLHEP::mm, -25*CLHEP::mm); // eta,phi
462 testElement(id, cellIds, positions, elements);
463
464 ATH_MSG_ALWAYS("----------------------------------------------");
465 ATH_MSG_ALWAYS(" A SCT Endcap element (outer type) other side");
466 ATH_MSG_ALWAYS("----------------------------------------------");
467 id = idHelper->wafer_id(2,3,15,0,1);
468 cellIds.clear();
469 positions.clear();
470 cellIds.emplace_back(532); // phi,eta
471 positions.emplace_back(12.727*CLHEP::mm, 20.534*CLHEP::mm); // eta,phi
472 positions.emplace_back(12.727*CLHEP::mm, -20.534*CLHEP::mm); // eta,phi
473 positions.emplace_back(3*CLHEP::mm, -25*CLHEP::mm); // eta,phi
474 testElement(id, cellIds, positions, elements);
475
476 // A middle fwd
477 ATH_MSG_ALWAYS("----------------------------------------------");
478 ATH_MSG_ALWAYS(" A SCT Endcap element (middle type)" );
479 ATH_MSG_ALWAYS("----------------------------------------------");
480 id = idHelper->wafer_id(2,1,15,1,0);
481 cellIds.clear();
482 positions.clear();
483 cellIds.emplace_back(532); // phi,eta
484 positions.emplace_back(12.727*CLHEP::mm, 4.534*CLHEP::mm); // eta,phi
485 testElement(id, cellIds, positions, elements);
486
487 // A truncated middle
488 ATH_MSG_ALWAYS("----------------------------------------------");
489 ATH_MSG_ALWAYS(" A SCT Endcap element (truncated middle type)" );
490 ATH_MSG_ALWAYS("----------------------------------------------");
491 id = idHelper->wafer_id(2,7,15,1,0);
492 cellIds.clear();
493 positions.clear();
494 cellIds.emplace_back(532); // phi,eta
495 positions.emplace_back(12.727*CLHEP::mm, 4.534*CLHEP::mm); // eta,phi
496 testElement(id, cellIds, positions, elements);
497
498 // A inner fwd
499 ATH_MSG_ALWAYS("----------------------------------------------");
500 ATH_MSG_ALWAYS(" A SCT Endcap element (inner type)" );
501 ATH_MSG_ALWAYS("----------------------------------------------");
502 id = idHelper->wafer_id(2,1,15,2,0);
503 cellIds.clear();
504 positions.clear();
505 cellIds.emplace_back(532); // phi,eta
506 positions.emplace_back(12.727*CLHEP::mm, 4.534*CLHEP::mm); // eta,phi
507 testElement(id, cellIds, positions, elements);
508 } // if manager = Pixel,SCT
509}
510
511void
513 // Get SiDetectorElementCollection from ConditionStore
515 const SiDetectorElementCollection* elementsC = detEle.retrieve();
516 ATH_MSG_INFO("Going to read from Conditions Store using handle: " << m_detEleCollKey.key());
517 if (elementsC==nullptr) {
518 ATH_MSG_FATAL(m_detEleCollKey.fullKey() << " could not be retrieved");
519 return;
520 }
521
522 // Get SiDetectorElementCollection from detector manager
523 const SiDetectorElementCollection* elementsM = m_manager->getDetectorElementCollection();
524
525 if (elementsC->size()!=elementsM->size()) {
526 ATH_MSG_FATAL("Sizes of SiDetectorElementCollections are different");
527 }
528
531 SiDetectorElementCollection::const_iterator elementMe = elementsM->end();
532 for (; elementM!=elementMe; ++elementC, ++elementM) {
533 auto diff = (*elementC)->center()-(*elementM)->center();
534 if (diff[0]!=0. or diff[1]!=0. or diff[2]!=0.) {
535 ATH_MSG_ALWAYS("----------------------------------------------");
536 ATH_MSG_ALWAYS("hash: " << (*elementC)->identifyHash());
537 ATH_MSG_ALWAYS("center (store) " << (*elementC)->center().transpose());
538 ATH_MSG_ALWAYS("center (manager) " << (*elementM)->center().transpose());
539 ATH_MSG_ALWAYS("diff (store-manager) " << diff.transpose());
540 ATH_MSG_ALWAYS("----------------------------------------------");
541 }
542 }
543}
544
545void
547 const std::vector<SiCellId> & cellIdVec,
548 const std::vector<Amg::Vector2D> & positionsVec,
549 const InDetDD::SiDetectorElementCollection* elements) const{
550 ATH_MSG_ALWAYS("----------------------------------------------");
551 const SiDetectorElement * element = nullptr;
552 if (elements) {
553 if (m_pixelIdHelper) {
554 element = elements->getDetectorElement(m_pixelIdHelper->wafer_hash(id));
555 } else if (m_sctIdHelper){
556 element = elements->getDetectorElement(m_sctIdHelper->wafer_hash(id));
557 }
558 } else {
559 element = m_manager->getDetectorElement(id);
560 }
561 if (element) {
562 IdentifierHash hashId = element->identifyHash();
564 ATH_MSG_ALWAYS(" width, minWidth, maxWidth, length, thickness (mm) = "
565 << element->width()/CLHEP::mm << " "
566 << element->minWidth()/CLHEP::mm << " "
567 << element->maxWidth()/CLHEP::mm << " "
568 << element->length()/CLHEP::mm << " "
569 << element->thickness()/CLHEP::mm
570 );
571 ATH_MSG_ALWAYS(" average etaPitch = " << element->etaPitch()/CLHEP::micrometer << " microns");
572 ATH_MSG_ALWAYS(" average phiPitch = " << element->phiPitch()/CLHEP::micrometer << " microns");
573 ATH_MSG_ALWAYS(" rMin, rMax, zMin, zMax (mm), phiMin, phiMax (deg) = "
574 << element->rMin()/CLHEP::mm << " "
575 << element->rMax()/CLHEP::mm << " "
576 << element->zMin()/CLHEP::mm << " "
577 << element->zMax()/CLHEP::mm << " "
578 << element->phiMin()/CLHEP::degree << " "
579 << element->phiMax()/CLHEP::degree
580 );
581 ATH_MSG_ALWAYS(" center, normal, etaAxis, phiAxis = "
582 << element->center() << " "
583 << element->normal() << " "
584 << element->etaAxis() << " "
585 << element->phiAxis()
586 );
587 ATH_MSG_ALWAYS(" center: r (mm) = " << element->center().perp()/CLHEP::mm
588 << ", phi (deg) = " << element->center().phi()/CLHEP::deg);
590 const EventContext &ctx = Gaudi::Hive::currentContext();
591 ATH_MSG_ALWAYS(" Temperature (C), bias voltage, depletion voltage: "
592 << m_siConditionsTool->temperature(hashId, ctx) << " "
593 << m_siConditionsTool->biasVoltage(hashId, ctx) << " "
594 << m_siConditionsTool->depletionVoltage(hashId, ctx));
595 }
596 ATH_MSG_ALWAYS(" sin(tilt), tilt (deg), sin(stereo), stereo (deg) = "
597 << element->sinTilt() << ", "
598 << asin(element->sinTilt())/CLHEP::degree << ", "
599 << element->sinStereo() << ", "
600 << asin(element->sinStereo())/CLHEP::degree);
601 ATH_MSG_ALWAYS(" Neighbours: ");
602 ATH_MSG_ALWAYS(" nextInEta: " << printElementId(element->nextInEta()) );
603 ATH_MSG_ALWAYS(" prevInEta: " << printElementId(element->prevInEta()) );
604 ATH_MSG_ALWAYS(" nextInPhi: " << printElementId(element->nextInPhi()) );
605 ATH_MSG_ALWAYS(" prevInPhi: " << printElementId(element->prevInPhi()) );
606 ATH_MSG_ALWAYS(" otherSide: " << printElementId(element->otherSide()) );
607
608 for (unsigned int iTestCell = 0; iTestCell < cellIdVec.size(); iTestCell++) {
609 SiCellId cellId = cellIdVec[iTestCell];
610 ATH_MSG_ALWAYS(" cell [phiIndex.etaIndex] = " << cellId);
611
612 // Test cell Id -> Identifier
613 Identifier fullCellId = element->identifierFromCellId(cellId);
614 ATH_MSG_ALWAYS(" identifier = ");
615 element->getIdHelper()->show(fullCellId);
616
617 // Test Identifier -> cell Id
618 SiCellId cellId2 = element->cellIdFromIdentifier(fullCellId);
619 ATH_MSG_ALWAYS(" extracted cell id [phiIndex.etaIndex] = " << cellId2);
620
621 InDetDD::SiLocalPosition localPosRaw1 = element->rawLocalPositionOfCell(cellId);
622 InDetDD::SiLocalPosition localPosRaw2 = element->rawLocalPositionOfCell(fullCellId);
623 ATH_MSG_ALWAYS(" raw localPosition (using cell id) (xPhi,xEta) = "
624 << localPosRaw1.xPhi() << ", " << localPosRaw1.xEta());
625 ATH_MSG_ALWAYS(" raw localPosition (using full id) (xPhi,xEta) = "
626 << localPosRaw2.xPhi() << ", " << localPosRaw2.xEta());
627 SiCellId cellIdRaw(element->cellIdOfPosition(localPosRaw1));
628 ATH_MSG_ALWAYS(" corresponding cell (phiIndex,etaIndex) = "
629 << cellIdRaw);
630 ATH_MSG_ALWAYS(" Number of connected cells (2 means ganged): "
631 << element->numberOfConnectedCells(cellId));
632 msg(MSG::ALWAYS) << " Connected cells";
633 for (int iCell=0; iCell < element->numberOfConnectedCells(cellId) ; iCell++) {
634 SiCellId connectedCellId = element->connectedCell(cellId, iCell);
635 msg(MSG::ALWAYS) << ", " << iCell << ": " << connectedCellId;
636 }
637 ATH_MSG_ALWAYS("In range: " << element->design().cellIdInRange(cellId));
638 }
639
640 for (unsigned int iTestPos = 0; iTestPos < positionsVec.size(); iTestPos++) {
641 const InDetDD::SiLocalPosition & localPosOrig = positionsVec[iTestPos];
642 ATH_MSG_ALWAYS(" Requested local pos (xPhi,xEta) = " << localPosOrig.xPhi() << ", " << localPosOrig.xEta());
643 //lost out to HepGeom here
644 Amg::Vector3D globalPos(element->globalPosition(localPosOrig));
645 ATH_MSG_ALWAYS(" Global pos = " << globalPos << ", r (mm) = " << globalPos.perp()/CLHEP::mm<< ", phi (deg) = " << globalPos.phi()/CLHEP::degree);
646
647 //...because i need a HepGeom::Point3D<double> to pass to element->localPosition...
648 InDetDD::SiLocalPosition localPosNew(element->localPosition(globalPos));
649 ATH_MSG_ALWAYS(" Returned local Pos (xPhi,xEta) = " << localPosNew.xPhi() << ", " << localPosNew.xEta());
650 // Some arbitrary tolerance picked out of the air.
651 double tolerance = 100*CLHEP::micrometer;
652 SiIntersect intersectState = element->inDetector(globalPos, tolerance, tolerance);
653 ATH_MSG_ALWAYS(" Intersects (tolerance = " << tolerance/CLHEP::mm << " mm) "
654 << " (in,out,nearBoundary,mayIntersect) : "
655 << intersectState.in() << ","
656 << intersectState.out() << ","
657 << intersectState.nearBoundary() << ","
658 << intersectState.mayIntersect());
659 ATH_MSG_ALWAYS(" Near bond gap: (tolerance = " << tolerance/CLHEP::mm << " mm) : "
660 << element->nearBondGap(globalPos, tolerance));
661 SiCellId returnedCellId = element->cellIdOfPosition(localPosNew);
662
663 ATH_MSG_ALWAYS(" Returned cell Id [phiIndex.etaIndex] = "
664 << returnedCellId);
665 ATH_MSG_ALWAYS(" using global position sin(tilt), tilt (deg), sin(stereo), stereo (deg) = "
666 << element->sinTilt(globalPos) << ", "
667 << asin(element->sinTilt(globalPos))/CLHEP::degree << ", "
668 << element->sinStereo(globalPos) << ", "
669 << asin(element->sinStereo(globalPos))/CLHEP::degree);
670 }
671 } else { // element == 0
672
673 ATH_MSG_ALWAYS(" ELEMENT MISSING!!!!!!!!!! ");
674 }
675 ATH_MSG_ALWAYS("----------------------------------------------");
676}
677
678std::string
680 if (element) {
681 return element->getIdHelper()->show_to_string(element->identify());
682 } else {
683 return "NONE";
684 }
685}
686// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
687
688
689// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
690
692 // Part 1: Get the messaging service, print where you are
693 ATH_MSG_INFO("finalize()");
694 return StatusCode::SUCCESS;
695}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_ALWAYS(x)
This is an Identifier helper class for the Pixel subdetector.
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
Definition Jet.cxx:631
This is an Identifier helper class for the SCT subdetector.
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
void show(Identifier id, const IdContext *context=0, char sep='.') const
Short print out of any identifier (optionally provide separation character - default is '.
std::string show_to_string(Identifier id, const IdContext *context=0, char sep='.') const
or provide the printout in string form
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
This is a "hash" representation of an Identifier.
virtual SiCellId cellIdInRange(const SiCellId &cellId) const =0
Check if cell is in range.
Identifier for the strip or pixel cell.
Definition SiCellId.h:29
Class to hold the SiDetectorElement objects to be put in the detector store.
const SiDetectorElement * getDetectorElement(const IdentifierHash &hash) const
Class to hold geometrical description of a silicon detector element.
virtual SiCellId cellIdFromIdentifier(const Identifier &identifier) const override final
SiCellId from Identifier.
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
double phiPitch() const
Pitch (inline methods).
bool nearBondGap(const Amg::Vector2D &localPosition, double etaTol) const
Test if near bond gap within tolerances.
const SiDetectorElement * prevInPhi() const
double sinStereo() const
Compute sin(stereo angle) at a given position: at center.
const SiDetectorElement * nextInPhi() const
const SiDetectorElement * otherSide() const
Useful for SCT only.
const SiDetectorElement * prevInEta() const
double sinTilt() const
Compute sin(tilt angle) at a given position: at center.
virtual Identifier identifierFromCellId(const SiCellId &cellId) const override final
Identifier <-> SiCellId (ie strip number or pixel eta_index,phi_index) Identifier from SiCellId (ie s...
const SiDetectorElement * nextInEta() const
class to run intersection tests
Definition SiIntersect.h:23
bool mayIntersect() const
Definition SiIntersect.h:66
bool nearBoundary() const
Definition SiIntersect.h:60
Class to represent a position in the natural frame of a silicon sensor, for Pixel and SCT For Pixel: ...
double xPhi() const
position along phi direction:
double xEta() const
position along eta direction:
Class to extract numerology for Pixel and SCT.
int numRingsForDisk(int disk) const
Number of rings (ie eta_module) in a disk.
bool useLayer(int layer) const
Check if layer exists.
bool useDisk(int disk) const
Check if disk exists.
int maxNumEndcapRings() const
Maximum number of rings in a disk.
int barrelId(int index) const
Barrel/endcap identifier for each barrel.
int numEtaModulesForLayer(int layer) const
Number of sectors in eta for a layer.
int maxNumPhiCells() const
Maximum number of cells in phi direction.
int numEndcaps() const
Number of endcaps.
int maxNumEtaCells() const
Maximum number of cells in eta direction.
int endEtaModuleForLayer(int layer) const
Last eta_module number + 1.
int maxNumStrips() const
Maximum number of strips.
int numLayers() const
Number of layers.
int numPhiModulesForLayer(int layer) const
Number of sectors in phi for a layer.
int numBarrels() const
Number of barrels.
int maxNumBarrelEta() const
Maximum number of modules in a barrel stave.
int beginEtaModuleForLayer(int layer) const
First eta_module number for a layer.
int numPhiModulesForDiskRing(int disk, int ring) const
Number of sectors in phi for a ring in a disk.
int endcapId(int index) const
Barrel/endcap identifier for each endcap.
bool skipEtaZeroForLayer(int layer) const
Check if eta_module=0 exists.
int numDisks() const
Number of disks.
double length() const
Length in eta direction (z - barrel, r - endcap).
SiCellId connectedCell(const SiCellId cellId, int number) const
Get the cell ids sharing the readout for this cell.
SiCellId cellIdOfPosition(const Amg::Vector2D &localPos) const
As in previous method but returns SiCellId.
Amg::Vector2D localPosition(const HepGeom::Point3D< double > &globalPosition) const
transform a global position into a 2D local position (reconstruction frame) (inline)
double width() const
Methods from design (inline).
virtual const Amg::Vector3D & normal() const override final
Get reconstruction local normal axes in global frame.
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
int numberOfConnectedCells(const SiCellId cellId) const
Test if readout cell has more than one diode associated with it.
double maxWidth() const
Max width.
HepGeom::Point3D< double > globalPosition(const HepGeom::Point3D< double > &localPos) const
transform a reconstruction local position into a global position (inline):
virtual const Amg::Vector3D & center() const override final
Center in global coordinates.
SiIntersect inDetector(const Amg::Vector2D &localPosition, double phiTol, double etaTol) const
Test that it is in the active region.
virtual Identifier identify() const override final
identifier of this detector element (inline)
double minWidth() const
Min width.
const AtlasDetectorID * getIdHelper() const
Returns the id helper (inline).
Amg::Vector2D rawLocalPositionOfCell(const SiCellId &cellId) const
Returns position (center) of cell.
double etaPitch() const
Pitch (inline methods).
This is an Identifier helper class for the Pixel subdetector.
Definition PixelID.h:69
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module) const
For a single crystal.
Definition PixelID.h:355
StatusCode execute(const EventContext &ctx)
Execute method.
ReadSiDetectorElements(const std::string &name, ISvcLocator *pSvcLocator)
const InDetDD::SiDetectorManager * m_manager
ToolHandle< ISiLorentzAngleTool > m_siLorentzAngleTool
ToolHandle< ISiliconConditionsTool > m_siConditionsTool
void printRandomAccess(const bool accessDuringInitialization)
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_detEleCollKey
const AtlasDetectorID * m_idHelper
void testElement(const Identifier &id, const std::vector< InDetDD::SiCellId > &cellIdVec, const std::vector< Amg::Vector2D > &positionsVec, const InDetDD::SiDetectorElementCollection *elements=nullptr) const
std::string printElementId(const InDetDD::SiDetectorElement *element) const
void printAllElements(const bool accessDuringInitialization)
This is an Identifier helper class for the SCT subdetector.
Definition SCT_ID.h:68
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module, int side) const
For a single side of module.
Definition SCT_ID.h:459
const_pointer_type retrieve()
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Message Stream Member.