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
77 ATH_CHECK(m_siConditionsTool.retrieve());
78 } else {
79 m_siLorentzAngleTool.disable();
80 m_siConditionsTool.disable();
81 }
82
83 // Initialize ReadCondHandleKey
84 ATH_CHECK(m_detEleCollKey.initialize());
85
86 // Print during initialize
87 if (m_doInit) {
88 printAllElements(true);
90 }
91 return StatusCode::SUCCESS;
92}
93
94
95StatusCode ReadSiDetectorElements::execute(const EventContext& /*ctx*/) {
96 // Only print out on first event
97 if (m_first && m_doExec) {
98 m_first = false;
99 printAllElements(false);
100 printRandomAccess(false);
102 }
103 return StatusCode::SUCCESS;
104}
105
106void ReadSiDetectorElements::printAllElements(const bool accessDuringInitialization) {
107 const bool useConditionStore = not accessDuringInitialization;
108 const SiDetectorElementCollection* elements = nullptr;
109 if (useConditionStore) {
110 // Get SiDetectorElementCollection from ConditionStore
112 elements = detEle.retrieve();
113 ATH_MSG_INFO("Going to read from Conditions Store using handle: " << m_detEleCollKey.key());
114 if (elements==nullptr) {
115 ATH_MSG_FATAL(m_detEleCollKey.fullKey() << " could not be retrieved");
116 return;
117 }
118 } else {
119 ATH_MSG_INFO("Going to read from detector manager: " << m_managerName);
120 elements = m_manager->getDetectorElementCollection();
121 }
122
123 // There are various ways you can access the elements. eg
124 // m_manager->getDetectorElement(idHash);
125 // m_manager->getDetectorElement(identifier);
126 //
127 // or access the whole collection or the iterators.
128 if (m_doLoop) {
129 for (const SiDetectorElement* element: *elements) {
130 if (!element) continue;
131 ATH_MSG_ALWAYS(m_idHelper->show_to_string(element->identify()));
132 // The id helper is also available through the elements
133 //
134 // element->getIdHelper()->show(element->identify());
135 //
136 ATH_MSG_ALWAYS(" center (x,y,z) = " << element->center().x() << "," << element->center().y() << "," << element->center().z());
137 ATH_MSG_ALWAYS(" center (r,phi,z) = " << element->center().perp() << "," << element->center().phi() << "," <<element->center().z());
139 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());
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) 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());
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(" Cell Id of (1,1) = " <<element->cellIdOfPosition(Amg::Vector2D(1,1)).etaIndex() << "," << element->cellIdOfPosition(Amg::Vector2D(1,1)).phiIndex());
144 ATH_MSG_ALWAYS(" Cell Id of (-1,-1) = " <<element->cellIdOfPosition(Amg::Vector2D(-1,-1)).etaIndex() << "," << element->cellIdOfPosition(Amg::Vector2D(-1,-1)).phiIndex());
145
146 }
147 ATH_MSG_ALWAYS(" Normal = " <<element->normal().perp() << "," << element->normal().phi() <<","<< element->normal().z());
148 ATH_MSG_ALWAYS(" sin(tilt), sin(stereo) = " << element->sinTilt() << " "
149 << element->sinStereo());
150 ATH_MSG_ALWAYS(" width, minWidth, maxWidth, length (mm) = "
151 << element->width()/CLHEP::mm << " "
152 << element->minWidth()/CLHEP::mm << " "
153 << element->maxWidth()/CLHEP::mm << " "
154 << element->length()/CLHEP::mm);
155
156 // These are no longer accessed through the detector element.
157 IdentifierHash hashId = element->identifyHash();
159 const EventContext &ctx = Gaudi::Hive::currentContext();
160 ATH_MSG_ALWAYS(" Temperature (C), bias voltage, depletion voltage: "
161 << m_siConditionsTool->temperature(hashId, ctx) << " "
162 << m_siConditionsTool->biasVoltage(hashId, ctx) << " "
163 << m_siConditionsTool->depletionVoltage(hashId, ctx));
164 ATH_MSG_ALWAYS(" Lorentz correction (mm), tanLorentzPhi = "
165 << m_siLorentzAngleTool->getLorentzShift(hashId, ctx)/CLHEP::mm << " "
166 << m_siLorentzAngleTool->getTanLorentzAngle(hashId, ctx));
167 }
168 ATH_MSG_ALWAYS(" HashId, Id : " << hashId << "\t" << element->identify().getString());
169 // Make some consistency tests for the identifier.
170 Identifier idTest;
171 IdentifierHash idHashTest;
172 if (m_managerName == "Pixel" || m_managerName == "ITkPixel") {
173 idTest = m_pixelIdHelper->wafer_id(hashId);
174 idHashTest = m_pixelIdHelper->wafer_hash(idTest);
175 } else if (m_sctIdHelper) {
176 idTest = m_sctIdHelper->wafer_id(hashId);
177 idHashTest = m_sctIdHelper->wafer_hash(idTest);
178 }
179 const SiDetectorElement * elementtest1 = nullptr;
180 const SiDetectorElement * elementtest2 = nullptr;
181 if (useConditionStore) {
182 // SiDetectorElementCollection::getDetectorElement supports only IdentifierHash as the argument.
183 if (m_pixelIdHelper) {
184 elementtest1 = elements->getDetectorElement(m_pixelIdHelper->wafer_hash(element->identify()));
185 } else if (m_sctIdHelper){
186 elementtest1 = elements->getDetectorElement(m_sctIdHelper->wafer_hash(element->identify()));
187 }
188 elementtest2 = elements->getDetectorElement(hashId);
189 } else {
190 elementtest1 = m_manager->getDetectorElement(element->identify());
191 elementtest2 = m_manager->getDetectorElement(hashId);
192 }
193 bool idOK = true;
194 if (idHashTest != hashId) {ATH_MSG_ALWAYS(" Id test 1 FAILED!"); idOK = false;}
195 if (idTest != element->identify()) {ATH_MSG_ALWAYS(" Id test 2 FAILED!"); idOK = false;}
196 if (elementtest1 != element) {ATH_MSG_ALWAYS(" Id test 3 FAILED!"); idOK = false;}
197 if (elementtest2 != element) {ATH_MSG_ALWAYS(" Id test 4 FAILED!"); idOK = false;}
198 if (idOK) ATH_MSG_ALWAYS(" ID tests OK") ;
200 const GeoTrf::Transform3D mytrf = element->transform();
201 const GeoTrf::Transform3D mytrfhit = element->transformHit();
202 ATH_MSG_ALWAYS("Transform: ");
203 ATH_MSG_ALWAYS("|"<<mytrf(2,0)<<","<<mytrf(2,1)<<","<<mytrf(2,2)<<"|");
204 ATH_MSG_ALWAYS("|"<<mytrf(1,0)<<","<<mytrf(1,1)<<","<<mytrf(1,2)<<"|");
205 ATH_MSG_ALWAYS("|"<<mytrf(0,0)<<","<<mytrf(0,1)<<","<<mytrf(0,2)<<"|");
206 ATH_MSG_ALWAYS("");
207 ATH_MSG_ALWAYS("TransformHit: ");
208 ATH_MSG_ALWAYS("|"<<mytrfhit(2,0)<<","<<mytrfhit(2,1)<<","<<mytrfhit(2,2)<<"|");
209 ATH_MSG_ALWAYS("|"<<mytrfhit(1,0)<<","<<mytrfhit(1,1)<<","<<mytrfhit(1,2)<<"|");
210 ATH_MSG_ALWAYS("|"<<mytrfhit(0,0)<<","<<mytrfhit(0,1)<<","<<mytrfhit(0,2)<<"|");
211 ATH_MSG_ALWAYS("");
212 }
214 ATH_MSG_ALWAYS("Depth Angle: "<<element->depthAngle());
215 if(element->depthDirection()) ATH_MSG_ALWAYS("Depth Direction True");
216 else ATH_MSG_ALWAYS("Depth Direction False");
217 ATH_MSG_ALWAYS("Eta Angle: "<<element->etaAngle());
218 if(element->etaDirection()) ATH_MSG_ALWAYS("Eta Direction True");
219 else ATH_MSG_ALWAYS("Eta Direction False");
220 ATH_MSG_ALWAYS("Phi Angle: "<<element->phiAngle());
221 if(element->phiDirection()) ATH_MSG_ALWAYS("Phi Direction True");
222 else ATH_MSG_ALWAYS("Phi Direction False");
223
224 if(std::abs(element->depthAngle())<0.5) ATH_MSG_ALWAYS("BAD DEPTH DIRECTION!");
225 if(std::abs(element->etaAngle())<0.5) ATH_MSG_ALWAYS("BAD ETA DIRECTION!");
226 if(std::abs(element->phiAngle())<0.5) ATH_MSG_ALWAYS("BAD PHI DIRECTION!");
227 }
228 //add divider between elements for readability
229 ATH_MSG_ALWAYS("-----------------------------");
230 }
231 }
232 // Testing numerology
233 const SiNumerology siNumerology(m_manager->numerology());
234 int nSides = 1;
235 if (m_sctIdHelper) nSides = 2;
236 int barrelCount = 0;
237 int barrelCountError = 0;
238 // Barrel
239 for (int iBarrelIndex = 0; iBarrelIndex < siNumerology.numBarrels(); iBarrelIndex++) {
240 int iBarrel = siNumerology.barrelId(iBarrelIndex);
241 ATH_MSG_ALWAYS("Barrel: " << iBarrel);
242 ATH_MSG_ALWAYS(" Num layers: " << siNumerology.numLayers());
243 for (int iLayer = 0; iLayer < siNumerology.numLayers(); iLayer++) {
244 ATH_MSG_ALWAYS(" Layer: " << iLayer);
245 if (!siNumerology.useLayer(iLayer))ATH_MSG_ALWAYS(" Layer not present");
246 ATH_MSG_ALWAYS(" Num Modules in Phi: " << siNumerology.numPhiModulesForLayer(iLayer));
247 ATH_MSG_ALWAYS(" Num Modules in Eta: " << siNumerology.numEtaModulesForLayer(iLayer));
248 for (int iPhi = 0; iPhi < siNumerology.numPhiModulesForLayer(iLayer); iPhi++) {
249 for (int iEta = siNumerology.beginEtaModuleForLayer(iLayer); iEta < siNumerology.endEtaModuleForLayer(iLayer); iEta++) {
250 if (!iEta && siNumerology.skipEtaZeroForLayer(iLayer)) continue;
251 for (int iSide = 0; iSide < nSides; iSide++) {
252 Identifier id;
253 if (m_managerName == "Pixel" || m_managerName == "ITkPixel"){
254 id = m_pixelIdHelper->wafer_id(iBarrel,iLayer,iPhi,iEta);
255 } else {
256 id = m_sctIdHelper->wafer_id(iBarrel,iLayer,iPhi,iEta,iSide);
257 }
258 const SiDetectorElement * element = nullptr;
259 if (useConditionStore) {
260 // SiDetectorElementCollection::getDetectorElement supports only IdentifierHash as the argument.
261 if (m_pixelIdHelper) {
262 element = elements->getDetectorElement(m_pixelIdHelper->wafer_hash(id));
263 } else if (m_sctIdHelper){
264 element = elements->getDetectorElement(m_sctIdHelper->wafer_hash(id));
265 }
266 } else {
267 element = m_manager->getDetectorElement(id);
268 }
269 barrelCount++;
270 if (!element) {
271 barrelCountError++;
272 ATH_MSG_ALWAYS(" No element found for id: " << m_idHelper->show_to_string(id));
273 } else {
274 // For extra safety in case some strip modules do not have two sides (eg in future geometries) one could add.
275 if (!element->otherSide()) iSide++;
276 ATH_MSG_ALWAYS(" " << m_idHelper->show_to_string(id));
277 }
278 } // iSide
279 } // iEta
280 } //iPhi
281 } //iLayer
282 } // Barrel
283
284 int endcapCount = 0;
285 int endcapCountError = 0;
286 // Endcap
287 for (int iEndcapIndex = 0; iEndcapIndex < siNumerology.numEndcaps(); iEndcapIndex++) {
288 int iEndcap = siNumerology.endcapId(iEndcapIndex);
289 ATH_MSG_ALWAYS("Endcap: " << iEndcap);
290 ATH_MSG_ALWAYS(" Num disks: " << siNumerology.numDisks());
291 for (int iDisk = 0; iDisk < siNumerology.numDisks(); iDisk++) {
292 ATH_MSG_ALWAYS(" Disk: " << iDisk);
293 if (!siNumerology.useDisk(iDisk))ATH_MSG_ALWAYS(" Disk not present");
294 ATH_MSG_ALWAYS(" Num Rings: " << siNumerology.numRingsForDisk(iDisk));
295 for (int iEta = 0; iEta < siNumerology.numRingsForDisk(iDisk); iEta++) {
296 ATH_MSG_ALWAYS(" Ring: " << iEta);
297 ATH_MSG_ALWAYS(" Num Modules in Phi: " << siNumerology.numPhiModulesForDiskRing(iDisk,iEta));
298 for (int iPhi = 0; iPhi < siNumerology.numPhiModulesForDiskRing(iDisk,iEta); iPhi++) {
299 for (int iSide = 0; iSide < nSides; iSide++) {
300 Identifier id;
301 if (m_pixelIdHelper) {
302 id = m_pixelIdHelper->wafer_id(iEndcap,iDisk,iPhi,iEta);
303 } else if (m_sctIdHelper){
304 id = m_sctIdHelper->wafer_id(iEndcap,iDisk,iPhi,iEta,iSide);
305 }
306 const SiDetectorElement * element = m_manager->getDetectorElement(id);
307 endcapCount++;
308 if (!element) {
309 endcapCountError++;
310 ATH_MSG_ALWAYS(" No element found for id: " << m_idHelper->show_to_string(id));
311 } else {
312 // For extra safety in case some strip modules do not have two sides (eg in future geometries) one could add.
313 if (!element->otherSide()) iSide++;
314 ATH_MSG_ALWAYS(" " << m_idHelper->show_to_string(id));
315 }
316 } // iSide
317 } // iEta
318 } //iPhi
319 } //iDisk
320 } // Endcap;
321
322 ATH_MSG_ALWAYS("Number of barrel elements : " << barrelCount);
323 ATH_MSG_ALWAYS("Number not found : " << barrelCountError);
324 ATH_MSG_ALWAYS("Number of endcap elements : " << endcapCount);
325 ATH_MSG_ALWAYS("Number not found : " << endcapCountError);
326
327 // Maximums
328 ATH_MSG_ALWAYS("MaxNumBarrelEta: " << siNumerology.maxNumBarrelEta());
329 ATH_MSG_ALWAYS("MaxNumEndcapRings: " << siNumerology.maxNumEndcapRings());
330 ATH_MSG_ALWAYS("MaxNumStrips: " << siNumerology.maxNumStrips());
331 ATH_MSG_ALWAYS("MaxNumPhiCells: " << siNumerology.maxNumPhiCells());
332 ATH_MSG_ALWAYS("MaxNumEtaCells: " << siNumerology.maxNumEtaCells());
333
334 ATH_MSG_ALWAYS("Num Designs: " << m_manager->numDesigns());
335}
336
337
338void ReadSiDetectorElements::printRandomAccess(const bool accessDuringInitialization) {
339 ATH_MSG_INFO("printRandomAccess()");
340
341 const bool useConditionStore = (m_managerName == "SCT" and (not accessDuringInitialization));
342 const SiDetectorElementCollection* elements = nullptr;
343 if (useConditionStore) {
344 // Get SiDetectorElementCollection from ConditionStore
346 elements = detEle.retrieve();
347 if (elements==nullptr) {
348 ATH_MSG_FATAL(m_detEleCollKey.fullKey() << " could not be retrieved");
349 return;
350 }
351 }
352
353 // Some random access
354 if (m_pixelIdHelper) {
355 //const PixelID * idHelper = dynamic_cast<const PixelID *>(m_manager->getIdHelper());
356 const PixelID * idHelper = m_pixelIdHelper;
357 Identifier id;
358 std::vector<SiCellId> cellIds;
359 std::vector<Amg::Vector2D> positions;
360 // wafer_id(barrel_ec, layer_disk, phi_module, eta_module)
361 // A barrel element
362 ATH_MSG_ALWAYS("----------------------------------------------");
363 ATH_MSG_ALWAYS(" A Pixel Barrel element (non B-layer) " );
364 ATH_MSG_ALWAYS("----------------------------------------------");
365 id = idHelper->wafer_id(0,1,15,-3);
366 cellIds.emplace_back(32,8); // phi,eta
367 //add a range of cells from 151 to 175
368 for (int i(151);i != 176; ++i){
369 cellIds.emplace_back(i,8); // phi,eta
370 }
371 cellIds.emplace_back(-1,1); // phi,eta
372 cellIds.emplace_back(0,1); // phi,eta
373 cellIds.emplace_back(1,-1); // phi,eta
374 cellIds.emplace_back(1,0); // phi,eta
375 cellIds.emplace_back(327,1); // phi,eta
376 cellIds.emplace_back(328,1); // phi,eta
377 cellIds.emplace_back(1,143); // phi,eta
378 cellIds.emplace_back(1,144); // phi,eta
379 positions.emplace_back(12.727*CLHEP::mm, 4.534*CLHEP::mm); // eta,phi
380 testElement(id, cellIds, positions, elements);
381
382 // A barrel element (B-Layer)
383 ATH_MSG_ALWAYS("----------------------------------------------");
384 ATH_MSG_ALWAYS(" A Pixel Barrel element (B-layer) " );
385 ATH_MSG_ALWAYS("----------------------------------------------");
386 id = idHelper->wafer_id(0,0,7,-3);
387 cellIds.clear();
388 positions.clear();
389 cellIds.emplace_back(32,8); // phi,eta
390 positions.emplace_back(12.727*CLHEP::mm, 4.534*CLHEP::mm); // eta,phi
391 testElement(id, cellIds, positions, elements);
392
393 // An endcap element
394 ATH_MSG_ALWAYS("----------------------------------------------");
395 ATH_MSG_ALWAYS(" A Pixel Endcap element" );
396 ATH_MSG_ALWAYS("----------------------------------------------");
397 id = idHelper->wafer_id(2,2,13,0);
398 cellIds.emplace_back(182,75); // phi,eta
399 positions.emplace_back(0*CLHEP::mm, 0*CLHEP::mm); // eta,phi
400 positions.emplace_back(30.4*CLHEP::mm, 8.2*CLHEP::mm); // eta,phi - on edge
401 positions.emplace_back(12*CLHEP::mm, -8.15*CLHEP::mm); // eta,phi - near edge
402 positions.emplace_back(12*CLHEP::mm, -8.25*CLHEP::mm); // eta,phi - near edge
403 positions.emplace_back(12*CLHEP::mm, -8.35*CLHEP::mm); // eta,phi - outside
404 testElement(id, cellIds, positions, elements);
405
406
407 } else if (m_sctIdHelper) {
408 const SCT_ID * idHelper = m_sctIdHelper;
409 Identifier id;
410 std::vector<SiCellId> cellIds;
411 std::vector<Amg::Vector2D> positions;
412
413
414 // wafer_id(barrel_ec, layer_disk, phi_module, eta_module, side)
415 // A barrel element
416 ATH_MSG_ALWAYS("----------------------------------------------");
417 ATH_MSG_ALWAYS(" A SCT Barrel element" );
418 ATH_MSG_ALWAYS("----------------------------------------------");
419 id = idHelper->wafer_id(0,1,15,-3,0);
420 cellIds.clear();
421 positions.clear();
422 cellIds.emplace_back(32); // phi,eta
423 cellIds.emplace_back(1); // phi,eta
424 cellIds.emplace_back(0); // phi,eta
425 if (m_managerName == "SCT") {
426 cellIds.emplace_back(-1); // phi,eta
427 cellIds.emplace_back(-2); // phi,eta
428 cellIds.emplace_back(-3); // phi,eta
429 }
430 cellIds.emplace_back(767); // phi,eta
431 cellIds.emplace_back(768); // phi,eta
432 positions.emplace_back(12.727*CLHEP::mm, 4.534*CLHEP::mm); // eta,phi
433 testElement(id, cellIds, positions, elements);
434
435 // A barrel element (other side of above)
436 ATH_MSG_ALWAYS("----------------------------------------------");
437 ATH_MSG_ALWAYS(" A SCT Barrel element (other side of above) ");
438 ATH_MSG_ALWAYS("----------------------------------------------");
439 id = idHelper->wafer_id(0,1,15,-3,1);
440 cellIds.clear();
441 positions.clear();
442 cellIds.emplace_back(32); // phi,eta
443 positions.emplace_back(12.727*CLHEP::mm, 4.534*CLHEP::mm); // eta,phi
444 testElement(id, cellIds, positions, elements);
445
446 // A outer fwd
447 ATH_MSG_ALWAYS("----------------------------------------------");
448 ATH_MSG_ALWAYS(" A SCT Endcap element (outer type)" );
449 ATH_MSG_ALWAYS("----------------------------------------------");
450 id = idHelper->wafer_id(2,3,15,0,0);
451 cellIds.clear();
452 positions.clear();
453 cellIds.emplace_back(532); // phi,eta
454 cellIds.emplace_back(0); // phi,eta
455 if (m_managerName == "SCT") cellIds.emplace_back(-1); // phi,eta
456 cellIds.emplace_back(767); // phi,eta
457 cellIds.emplace_back(768); // phi,eta
458 positions.emplace_back(12.727*CLHEP::mm, 20.534*CLHEP::mm); // eta,phi
459 positions.emplace_back(12.727*CLHEP::mm, -20.534*CLHEP::mm); // eta,phi
460 positions.emplace_back(3*CLHEP::mm, -25*CLHEP::mm); // eta,phi
461 testElement(id, cellIds, positions, elements);
462
463 ATH_MSG_ALWAYS("----------------------------------------------");
464 ATH_MSG_ALWAYS(" A SCT Endcap element (outer type) other side");
465 ATH_MSG_ALWAYS("----------------------------------------------");
466 id = idHelper->wafer_id(2,3,15,0,1);
467 cellIds.clear();
468 positions.clear();
469 cellIds.emplace_back(532); // phi,eta
470 positions.emplace_back(12.727*CLHEP::mm, 20.534*CLHEP::mm); // eta,phi
471 positions.emplace_back(12.727*CLHEP::mm, -20.534*CLHEP::mm); // eta,phi
472 positions.emplace_back(3*CLHEP::mm, -25*CLHEP::mm); // eta,phi
473 testElement(id, cellIds, positions, elements);
474
475 // A middle fwd
476 ATH_MSG_ALWAYS("----------------------------------------------");
477 ATH_MSG_ALWAYS(" A SCT Endcap element (middle type)" );
478 ATH_MSG_ALWAYS("----------------------------------------------");
479 id = idHelper->wafer_id(2,1,15,1,0);
480 cellIds.clear();
481 positions.clear();
482 cellIds.emplace_back(532); // phi,eta
483 positions.emplace_back(12.727*CLHEP::mm, 4.534*CLHEP::mm); // eta,phi
484 testElement(id, cellIds, positions, elements);
485
486 // A truncated middle
487 ATH_MSG_ALWAYS("----------------------------------------------");
488 ATH_MSG_ALWAYS(" A SCT Endcap element (truncated middle type)" );
489 ATH_MSG_ALWAYS("----------------------------------------------");
490 id = idHelper->wafer_id(2,7,15,1,0);
491 cellIds.clear();
492 positions.clear();
493 cellIds.emplace_back(532); // phi,eta
494 positions.emplace_back(12.727*CLHEP::mm, 4.534*CLHEP::mm); // eta,phi
495 testElement(id, cellIds, positions, elements);
496
497 // A inner fwd
498 ATH_MSG_ALWAYS("----------------------------------------------");
499 ATH_MSG_ALWAYS(" A SCT Endcap element (inner type)" );
500 ATH_MSG_ALWAYS("----------------------------------------------");
501 id = idHelper->wafer_id(2,1,15,2,0);
502 cellIds.clear();
503 positions.clear();
504 cellIds.emplace_back(532); // phi,eta
505 positions.emplace_back(12.727*CLHEP::mm, 4.534*CLHEP::mm); // eta,phi
506 testElement(id, cellIds, positions, elements);
507 } // if manager = Pixel,SCT
508}
509
510void
512 // Get SiDetectorElementCollection from ConditionStore
514 const SiDetectorElementCollection* elementsC = detEle.retrieve();
515 ATH_MSG_INFO("Going to read from Conditions Store using handle: " << m_detEleCollKey.key());
516 if (elementsC==nullptr) {
517 ATH_MSG_FATAL(m_detEleCollKey.fullKey() << " could not be retrieved");
518 return;
519 }
520
521 // Get SiDetectorElementCollection from detector manager
522 const SiDetectorElementCollection* elementsM = m_manager->getDetectorElementCollection();
523
524 if (elementsC->size()!=elementsM->size()) {
525 ATH_MSG_FATAL("Sizes of SiDetectorElementCollections are different");
526 }
527
530 SiDetectorElementCollection::const_iterator elementMe = elementsM->end();
531 for (; elementM!=elementMe; ++elementC, ++elementM) {
532 auto diff = (*elementC)->center()-(*elementM)->center();
533 if (diff[0]!=0. or diff[1]!=0. or diff[2]!=0.) {
534 ATH_MSG_ALWAYS("----------------------------------------------");
535 ATH_MSG_ALWAYS("hash: " << (*elementC)->identifyHash());
536 ATH_MSG_ALWAYS("center (store) " << (*elementC)->center().transpose());
537 ATH_MSG_ALWAYS("center (manager) " << (*elementM)->center().transpose());
538 ATH_MSG_ALWAYS("diff (store-manager) " << diff.transpose());
539 ATH_MSG_ALWAYS("----------------------------------------------");
540 }
541 }
542}
543
544void
546 const std::vector<SiCellId> & cellIdVec,
547 const std::vector<Amg::Vector2D> & positionsVec,
548 const InDetDD::SiDetectorElementCollection* elements) const{
549 ATH_MSG_ALWAYS("----------------------------------------------");
550 const SiDetectorElement * element = nullptr;
551 if (elements) {
552 if (m_pixelIdHelper) {
553 element = elements->getDetectorElement(m_pixelIdHelper->wafer_hash(id));
554 } else if (m_sctIdHelper){
555 element = elements->getDetectorElement(m_sctIdHelper->wafer_hash(id));
556 }
557 } else {
558 element = m_manager->getDetectorElement(id);
559 }
560 if (element) {
561 IdentifierHash hashId = element->identifyHash();
563 ATH_MSG_ALWAYS(" width, minWidth, maxWidth, length, thickness (mm) = "
564 << element->width()/CLHEP::mm << " "
565 << element->minWidth()/CLHEP::mm << " "
566 << element->maxWidth()/CLHEP::mm << " "
567 << element->length()/CLHEP::mm << " "
568 << element->thickness()/CLHEP::mm
569 );
570 ATH_MSG_ALWAYS(" average etaPitch = " << element->etaPitch()/CLHEP::micrometer << " microns");
571 ATH_MSG_ALWAYS(" average phiPitch = " << element->phiPitch()/CLHEP::micrometer << " microns");
572 ATH_MSG_ALWAYS(" rMin, rMax, zMin, zMax (mm), phiMin, phiMax (deg) = "
573 << element->rMin()/CLHEP::mm << " "
574 << element->rMax()/CLHEP::mm << " "
575 << element->zMin()/CLHEP::mm << " "
576 << element->zMax()/CLHEP::mm << " "
577 << element->phiMin()/CLHEP::degree << " "
578 << element->phiMax()/CLHEP::degree
579 );
580 ATH_MSG_ALWAYS(" center, normal, etaAxis, phiAxis = "
581 << element->center() << " "
582 << element->normal() << " "
583 << element->etaAxis() << " "
584 << element->phiAxis()
585 );
586 ATH_MSG_ALWAYS(" center: r (mm) = " << element->center().perp()/CLHEP::mm
587 << ", phi (deg) = " << element->center().phi()/CLHEP::deg);
589 const EventContext &ctx = Gaudi::Hive::currentContext();
590 ATH_MSG_ALWAYS(" Temperature (C), bias voltage, depletion voltage: "
591 << m_siConditionsTool->temperature(hashId, ctx) << " "
592 << m_siConditionsTool->biasVoltage(hashId, ctx) << " "
593 << m_siConditionsTool->depletionVoltage(hashId, ctx));
594 }
595 ATH_MSG_ALWAYS(" sin(tilt), tilt (deg), sin(stereo), stereo (deg) = "
596 << element->sinTilt() << ", "
597 << asin(element->sinTilt())/CLHEP::degree << ", "
598 << element->sinStereo() << ", "
599 << asin(element->sinStereo())/CLHEP::degree);
600 ATH_MSG_ALWAYS(" Neighbours: ");
601 ATH_MSG_ALWAYS(" nextInEta: " << printElementId(element->nextInEta()) );
602 ATH_MSG_ALWAYS(" prevInEta: " << printElementId(element->prevInEta()) );
603 ATH_MSG_ALWAYS(" nextInPhi: " << printElementId(element->nextInPhi()) );
604 ATH_MSG_ALWAYS(" prevInPhi: " << printElementId(element->prevInPhi()) );
605 ATH_MSG_ALWAYS(" otherSide: " << printElementId(element->otherSide()) );
606
607 for (unsigned int iTestCell = 0; iTestCell < cellIdVec.size(); iTestCell++) {
608 SiCellId cellId = cellIdVec[iTestCell];
609 ATH_MSG_ALWAYS(" cell [phiIndex.etaIndex] = " << cellId);
610
611 // Test cell Id -> Identifier
612 Identifier fullCellId = element->identifierFromCellId(cellId);
613 ATH_MSG_ALWAYS(" identifier = ");
614 element->getIdHelper()->show(fullCellId);
615
616 // Test Identifier -> cell Id
617 SiCellId cellId2 = element->cellIdFromIdentifier(fullCellId);
618 ATH_MSG_ALWAYS(" extracted cell id [phiIndex.etaIndex] = " << cellId2);
619
620 InDetDD::SiLocalPosition localPosRaw1 = element->rawLocalPositionOfCell(cellId);
621 InDetDD::SiLocalPosition localPosRaw2 = element->rawLocalPositionOfCell(fullCellId);
622 ATH_MSG_ALWAYS(" raw localPosition (using cell id) (xPhi,xEta) = "
623 << localPosRaw1.xPhi() << ", " << localPosRaw1.xEta());
624 ATH_MSG_ALWAYS(" raw localPosition (using full id) (xPhi,xEta) = "
625 << localPosRaw2.xPhi() << ", " << localPosRaw2.xEta());
626 SiCellId cellIdRaw(element->cellIdOfPosition(localPosRaw1));
627 ATH_MSG_ALWAYS(" corresponding cell (phiIndex,etaIndex) = "
628 << cellIdRaw);
629 ATH_MSG_ALWAYS(" Number of connected cells (2 means ganged): "
630 << element->numberOfConnectedCells(cellId));
631 msg(MSG::ALWAYS) << " Connected cells";
632 for (int iCell=0; iCell < element->numberOfConnectedCells(cellId) ; iCell++) {
633 SiCellId connectedCellId = element->connectedCell(cellId, iCell);
634 msg(MSG::ALWAYS) << ", " << iCell << ": " << connectedCellId;
635 }
636 ATH_MSG_ALWAYS("In range: " << element->design().cellIdInRange(cellId));
637 }
638
639 for (unsigned int iTestPos = 0; iTestPos < positionsVec.size(); iTestPos++) {
640 const InDetDD::SiLocalPosition & localPosOrig = positionsVec[iTestPos];
641 ATH_MSG_ALWAYS(" Requested local pos (xPhi,xEta) = " << localPosOrig.xPhi() << ", " << localPosOrig.xEta());
642 //lost out to HepGeom here
643 Amg::Vector3D globalPos(element->globalPosition(localPosOrig));
644 ATH_MSG_ALWAYS(" Global pos = " << globalPos << ", r (mm) = " << globalPos.perp()/CLHEP::mm<< ", phi (deg) = " << globalPos.phi()/CLHEP::degree);
645
646 //...because i need a HepGeom::Point3D<double> to pass to element->localPosition...
647 InDetDD::SiLocalPosition localPosNew(element->localPosition(globalPos));
648 ATH_MSG_ALWAYS(" Returned local Pos (xPhi,xEta) = " << localPosNew.xPhi() << ", " << localPosNew.xEta());
649 // Some arbitrary tolerance picked out of the air.
650 double tolerance = 100*CLHEP::micrometer;
651 SiIntersect intersectState = element->inDetector(globalPos, tolerance, tolerance);
652 ATH_MSG_ALWAYS(" Intersects (tolerance = " << tolerance/CLHEP::mm << " mm) "
653 << " (in,out,nearBoundary,mayIntersect) : "
654 << intersectState.in() << ","
655 << intersectState.out() << ","
656 << intersectState.nearBoundary() << ","
657 << intersectState.mayIntersect());
658 ATH_MSG_ALWAYS(" Near bond gap: (tolerance = " << tolerance/CLHEP::mm << " mm) : "
659 << element->nearBondGap(globalPos, tolerance));
660 SiCellId returnedCellId = element->cellIdOfPosition(localPosNew);
661
662 ATH_MSG_ALWAYS(" Returned cell Id [phiIndex.etaIndex] = "
663 << returnedCellId);
664 ATH_MSG_ALWAYS(" using global position sin(tilt), tilt (deg), sin(stereo), stereo (deg) = "
665 << element->sinTilt(globalPos) << ", "
666 << asin(element->sinTilt(globalPos))/CLHEP::degree << ", "
667 << element->sinStereo(globalPos) << ", "
668 << asin(element->sinStereo(globalPos))/CLHEP::degree);
669 }
670 } else { // element == 0
671
672 ATH_MSG_ALWAYS(" ELEMENT MISSING!!!!!!!!!! ");
673 }
674 ATH_MSG_ALWAYS("----------------------------------------------");
675}
676
677std::string
679 if (element) {
680 return element->getIdHelper()->show_to_string(element->identify());
681 } else {
682 return "NONE";
683 }
684}
685// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
686
687
688// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
689
691 // Part 1: Get the messaging service, print where you are
692 ATH_MSG_INFO("finalize()");
693 return StatusCode::SUCCESS;
694}
#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.