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