ATLAS Offline Software
Loading...
Searching...
No Matches
PixelDetectorFactory.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
7#include "PixelSwitches.h"
8
9// Envelope, as a starting point of the geometry
10#include "GeoPixelEnvelope.h"
11
12// GeoModel includes
13#include "GeoModelKernel/GeoNameTag.h"
14#include "GeoModelKernel/GeoPhysVol.h"
15#include "GeoModelKernel/GeoAlignableTransform.h"
16#include "GaudiKernel/SystemOfUnits.h"
17
18// InDetReadoutGeometry
23
24#include "DBPixelGeoManager.h"
26
28
30
31
34
36 const PixelSwitches & switches)
37 : InDetDD::DetectorFactoryBase(athenaComps),
38 m_detectorManager(nullptr),
40{
41 // Create the detector manager
43
44 // Create the geometry manager.
45 m_geometryManager = std::make_unique<DBPixelGeoManager>(athenaComps);
46
47 // Pass the switches
48 m_geometryManager->SetServices(switches.services());
49 m_geometryManager->SetServicesOnLadder(switches.servicesOnLadder());
50 m_geometryManager->SetDC1Geometry(switches.dc1Geometry());
51 m_geometryManager->SetAlignable(switches.alignable());
52 m_geometryManager->SetInitialLayout(switches.initialLayout());
53 m_geometryManager->SetIBL(switches.ibl());
54
55 // get switch for DBM
56 m_geometryManager->SetDBMFlag(switches.dbm());
57 msg(MSG::INFO) << "DBM switch = SetDBMFlag: "<< m_geometryManager->dbm() << endmsg;
58
59 // Create SiCommonItems ans store it in geometry manager.
60 // These are items that are shared by all elements
61 std::unique_ptr<SiCommonItems> commonItems{std::make_unique<SiCommonItems>(athenaComps->getIdHelper())};
62 m_geometryManager->setCommonItems(commonItems.get());
63
64 // Add SiCommonItems to PixelDetectorManager to hold and delete it.
65 m_detectorManager->setCommonItems(std::move(commonItems));
66
67 // Determine if initial layer and tag from the id dict are consistent
68 bool initialLayoutIdDict = (m_detectorManager->tag() == "initial_layout");
69 if (m_geometryManager->InitialLayout() != initialLayoutIdDict ) {
70 if(msgLvl(MSG::WARNING))
71 msg(MSG::WARNING) << "IdDict tag is \"" << m_detectorManager->tag()
72 << "\" which is inconsistent with the layout choosen!"
73 << endmsg;
74 }
75
76
77 //
78 // Set Version information
79 //
80 std::string versionTag = m_geometryManager->versionTag();
81 std::string versionName = m_geometryManager->versionName();
82 std::string layout = m_geometryManager->versionLayout();
83 std::string description = m_geometryManager->versionDescription() ;
84 int versionMajorNumber = 5;
85 int versionMinorNumber = 1;
86 int versionPatchNumber = 0;
87
88 if (m_geometryManager->InitialLayout()) {
89 layout = "Initial";
90 }
91
92 InDetDD::Version version(versionTag,
93 versionName,
94 layout,
96 versionMajorNumber,
97 versionMinorNumber,
98 versionPatchNumber);
99 m_detectorManager->setVersion(version);
100
102
103}
104
105
109
110
111//## Other Operations (implementation)
112void PixelDetectorFactory::create(GeoPhysVol *world)
113{
114 if(msgLvl(MSG::INFO)) {
115 msg(MSG::INFO) << "Building Pixel Detector" << endmsg;
116 msg(MSG::INFO) << " " << m_detectorManager->getVersion().fullDescription() << endmsg;
117 }
118 // Printout the parameters that are different in DC1 and DC2.
119 m_geometryManager->SetCurrentLD(0);
120 m_geometryManager->SetBarrel();
121 if(msgLvl(MSG::DEBUG)) {
122 msg(MSG::DEBUG) << " B-Layer basic eta pitch: " << m_geometryManager->DesignPitchZ()/Gaudi::Units::micrometer << "um" << endmsg;
123 msg(MSG::DEBUG) << " B-Layer sensor thickness: " << m_geometryManager->PixelBoardThickness()/Gaudi::Units::micrometer << "um" << endmsg;
124 }
125
126 // Top level transform
127 GeoTrf::Transform3D topTransform = m_geometryManager->partTransform("Pixel");
128
129
130 //
131 // Create the Pixel Envelope...
132 GeoPixelEnvelope pe (m_detectorManager, m_geometryManager.get(), nullptr, nullptr, nullptr);
133 GeoVPhysVol* pephys = pe.Build() ;
134
135 //
136 // Add this to the world
137 //
138 world->add(new GeoNameTag("Pixel"));
139 GeoAlignableTransform * transform = new GeoAlignableTransform(topTransform);
140 world->add(transform);
141 world->add(pephys);
142
143 // Store alignable transform
144 Identifier id = m_geometryManager->getIdHelper()->wafer_id(0,0,0,0);
145 m_detectorManager->addAlignableTransform(2, id, transform, pephys);
146
147 // Add this to the list of top level physical volumes:
148 //
149 m_detectorManager->addTreeTop(pephys);
150
151
152 // Initialize the neighbours
153 m_detectorManager->initNeighbours();
154
155 // Set maximum rows/columns in numerology
156 for (int iDesign = 0; iDesign < m_detectorManager->numDesigns(); iDesign++) {
157 m_detectorManager->numerology().setMaxNumPhiCells(m_detectorManager->getPixelDesign(iDesign)->rows());
158 m_detectorManager->numerology().setMaxNumEtaCells(m_detectorManager->getPixelDesign(iDesign)->columns());
159 }
160
161 // Register the callbacks and keys and the level corresponding to the key.
162 if (m_geometryManager->Alignable()) {
163
165 m_detectorManager->addAlignFolderType(InDetDD::static_run1);
166 m_detectorManager->addFolder("/Indet/Align");
167 m_detectorManager->addChannel("/Indet/Align/ID", 2, InDetDD::global);
168 m_detectorManager->addChannel("/Indet/Align/PIX", 1, InDetDD::global);
169 m_detectorManager->addChannel("/Indet/Align/PIXB1", 0, InDetDD::local);
170 m_detectorManager->addChannel("/Indet/Align/PIXB2", 0, InDetDD::local);
171 m_detectorManager->addChannel("/Indet/Align/PIXB3", 0, InDetDD::local);
172 m_detectorManager->addChannel("/Indet/Align/PIXB4", 0, InDetDD::local);
173 m_detectorManager->addChannel("/Indet/Align/PIXEA1", 0, InDetDD::local);
174 m_detectorManager->addChannel("/Indet/Align/PIXEA2", 0, InDetDD::local);
175 m_detectorManager->addChannel("/Indet/Align/PIXEA3", 0, InDetDD::local);
176 m_detectorManager->addChannel("/Indet/Align/PIXEC1", 0, InDetDD::local);
177 m_detectorManager->addChannel("/Indet/Align/PIXEC2", 0, InDetDD::local);
178 m_detectorManager->addChannel("/Indet/Align/PIXEC3", 0, InDetDD::local);
179 }
180
181 else {
183 m_detectorManager->addGlobalFolder("/Indet/AlignL1/ID");
184 m_detectorManager->addGlobalFolder("/Indet/AlignL2/PIX");
185 m_detectorManager->addChannel("/Indet/AlignL1/ID", 2, InDetDD::global);
186 m_detectorManager->addChannel("/Indet/AlignL2/PIX", 1, InDetDD::global);
187 m_detectorManager->addFolder("/Indet/AlignL3");
188 m_detectorManager->addChannel("/Indet/AlignL3/PIXB1", 0, InDetDD::local);
189 m_detectorManager->addChannel("/Indet/AlignL3/PIXB2", 0, InDetDD::local);
190 m_detectorManager->addChannel("/Indet/AlignL3/PIXB3", 0, InDetDD::local);
191 m_detectorManager->addChannel("/Indet/AlignL3/PIXB4", 0, InDetDD::local);
192 m_detectorManager->addChannel("/Indet/AlignL3/PIXEA1", 0, InDetDD::local);
193 m_detectorManager->addChannel("/Indet/AlignL3/PIXEA2", 0, InDetDD::local);
194 m_detectorManager->addChannel("/Indet/AlignL3/PIXEA3", 0, InDetDD::local);
195 m_detectorManager->addChannel("/Indet/AlignL3/PIXEC1", 0, InDetDD::local);
196 m_detectorManager->addChannel("/Indet/AlignL3/PIXEC2", 0, InDetDD::local);
197 m_detectorManager->addChannel("/Indet/AlignL3/PIXEC3", 0, InDetDD::local);
198 }
199
200 // This is the new LB-IOV sensitive IBL bowing DB
201 m_detectorManager->addSpecialFolder("/Indet/IBLDist");
202
203 }
204
205 // Check that there are no missing elements.
206 // Bypass checks for standard ATLAS.
207 if (m_geometryManager->ibl()) {
208 doChecks();
209 }
210}
211
216
217void
219{
220 const PixelID * idHelper = m_geometryManager->athenaComps()->getIdHelper();
221 const PixelDetectorManager * manager = m_detectorManager;
222
223 msg(MSG::INFO) << "Doing consistency checks." << endmsg;
224
225 unsigned int maxHash = idHelper->wafer_hash_max();
226
227 int count = 0;
228 int missingCount = 0;
230 for (iter = manager->getDetectorElementBegin(); iter != manager->getDetectorElementEnd(); ++iter){
231 count++;
232 const InDetDD::SiDetectorElement * element = *iter;
233 if (!element) {
234 msg(MSG::WARNING) << "MISSING ELEMENT!!!!!!!!!!! - Element # " << count-1 << endmsg;
235 missingCount++;
236 }
237 }
238
239 if (missingCount) {
240 msg(MSG::ERROR) << "There are missing elements in element array." << endmsg;
241 msg(MSG::INFO) << "Number of elements: " << count << endmsg;
242 msg(MSG::INFO) << "Number missing: " << missingCount << endmsg;
243 }
244
245
246 // ***********************************************************************************
247 // Loop over modules
248 // ***********************************************************************************
249
250 // Barrel
251 int barrelCount = 0;
252 int barrelCountError = 0;
253 for (int iBarrelIndex = 0; iBarrelIndex < manager->numerology().numBarrels(); iBarrelIndex++) {
254 int iBarrel = manager->numerology().barrelId(iBarrelIndex);
255 for (int iLayer = 0; iLayer < manager->numerology().numLayers(); iLayer++) {
256
257 // TEMPORARY FIX
258 // Temporary fix for IBL. Numerology class needs to be fixed.
259 m_geometryManager->SetCurrentLD(iLayer);
260 int etaCorrection = 0;
261 if (!m_geometryManager->allowSkipEtaZero() && manager->numerology().skipEtaZeroForLayer(iLayer)) {
262 //std::cout << "ETA CORRECTION" << std::endl;
263 etaCorrection = 1;
264 }
265 // END TEMPORARY FIX
266
267 if (manager->numerology().useLayer(iLayer)) {
268 for (int iPhi = 0; iPhi < manager->numerology().numPhiModulesForLayer(iLayer); iPhi++) {
269 for (int iEta = manager->numerology().beginEtaModuleForLayer(iLayer);
270 iEta < manager->numerology().endEtaModuleForLayer(iLayer) - etaCorrection;
271 iEta++) {
272 //if (!iEta && manager->numerology().skipEtaZeroForLayer(iLayer)) continue;
273 if (!etaCorrection && !iEta && manager->numerology().skipEtaZeroForLayer(iLayer)) continue; // TEMPORARY FIX
274 Identifier id = idHelper->wafer_id(iBarrel,iLayer,iPhi,iEta);
275 const InDetDD::SiDetectorElement * element = manager->getDetectorElement(id);
276 barrelCount++;
277 std::stringstream ostr;
278 ostr << "[2.1 . " << iBarrel << " . " << iLayer << " . " << iPhi << " . " << iEta << " . 0]";
279 if (!element) {
280 barrelCountError++;
281 msg(MSG::WARNING) << " No element found for id: " << ostr.str() << " " << idHelper->show_to_string(id) << endmsg;
282 }
283 } // iEta
284 } //iPhi
285 }
286 } //iLayer
287 } // Barrel
288
289
290 // Endcap
291 int endcapCount = 0;
292 int endcapCountError = 0;
293 for (int iEndcapIndex = 0; iEndcapIndex < manager->numerology().numEndcaps(); iEndcapIndex++) {
294 int iEndcap = manager->numerology().endcapId(iEndcapIndex);
295 for (int iDisk = 0; iDisk < manager->numerology().numDisks(); iDisk++) {
296 if (manager->numerology().useDisk(iDisk)) {
297 for (int iEta = 0; iEta < manager->numerology().numRingsForDisk(iDisk); iEta++) {
298 for (int iPhi = 0; iPhi < manager->numerology().numPhiModulesForDiskRing(iDisk,iEta); iPhi++) {
299 Identifier id = idHelper->wafer_id(iEndcap,iDisk,iPhi,iEta);
300 const InDetDD::SiDetectorElement * element = manager->getDetectorElement(id);
301 endcapCount++;
302 std::stringstream ostr;
303 ostr << "[2.1." << iEndcap << "." << iDisk << "." << iPhi << "." << iEta << ".0]";
304 if (!element) {
305 endcapCountError++;
306 msg(MSG::WARNING) << " No element found for id: " << ostr.str() << " " << idHelper->show_to_string(id) << endmsg;
307 }
308 } // iEta
309 } //iPhi
310 }
311 } //iDisk
312 } // Endcap;
313
314 // Check DBM endcap modules
315 int endcapCountDBM = 0;
316 int endcapCountErrorDBM = 0;
317 if (m_geometryManager->dbm()) {
318 // endcapCount += 24;
319
320 // Endcap
321 for (int iEndcapIndex = 0; iEndcapIndex < manager->numerology().numEndcapsDBM(); iEndcapIndex++) {
322 int iEndcap = manager->numerology().endcapIdDBM(iEndcapIndex);
323 for (int iDisk = 0; iDisk < manager->numerology().numDisksDBM(); iDisk++) {
324 if (manager->numerology().useDiskDBM(iDisk)) {
325 for (int iEta = 0; iEta < manager->numerology().numRingsForDiskDBM(iDisk); iEta++) {
326 for (int iPhi = 0; iPhi < manager->numerology().numPhiModulesForDiskRingDBM(iDisk,iEta); iPhi++) {
327 Identifier id = idHelper->wafer_id(iEndcap,iDisk,iPhi,iEta);
328 const InDetDD::SiDetectorElement * element = manager->getDetectorElement(id);
329 endcapCountDBM++;
330 std::stringstream ostr;
331 ostr << "[2.1." << iEndcap << "." << iDisk << "." << iPhi << "." << iEta << ".0]";
332 if (!element) {
333 endcapCountErrorDBM++;
334 msg(MSG::WARNING) << " No element found for id (DBM): " << ostr.str() << " " << idHelper->show_to_string(id) << endmsg;
335 }
336 } // iEta
337 } //iPhi
338 }
339 } //iDisk
340 } // Endcap;
341 }
342
343 if (barrelCountError || endcapCountError || endcapCountErrorDBM) {
344 msg(MSG::ERROR) << "There are elements which cannot be found." << endmsg;
345 msg(MSG::INFO) << "Number of barrel elements not found : " << barrelCountError << endmsg;
346 msg(MSG::INFO) << "Number of pixel endcap elements not found : " << endcapCountError << endmsg;
347 msg(MSG::INFO) << "Number of DBM endcap elements not found : " << endcapCountErrorDBM << endmsg;
348 }
349
350 if ( barrelCount+endcapCount+endcapCountDBM != int(maxHash)) {
351 msg(MSG::ERROR) << "Total count does not match maxHash." << endmsg;
352 msg(MSG::INFO) << "Number of barrel elements : " << barrelCount << endmsg;
353 msg(MSG::INFO) << "Number of endcap elements : " << endcapCount << endmsg;
354 msg(MSG::INFO) << "Number of endcap elements (DBM) : " << endcapCountDBM << endmsg;
355 msg(MSG::INFO) << "Total : " << barrelCount+endcapCount+endcapCountDBM << endmsg;
356 msg(MSG::INFO) << "MaxHash : " << maxHash << endmsg;
357 }
358
359 msg(MSG::INFO) << "Number of barrel elements : " << barrelCount << endmsg;
360 msg(MSG::INFO) << "Number of endcap elements : " << endcapCount << endmsg;
361 msg(MSG::INFO) << "Number of endcap elements (DBM) : " << endcapCountDBM << endmsg;
362 msg(MSG::INFO) << "Total : " << barrelCount+endcapCount+endcapCountDBM << endmsg;
363 msg(MSG::INFO) << "MaxHash : " << maxHash << endmsg;
364
365}
366
367
#define endmsg
This is an Identifier helper class for the Pixel subdetector.
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
DetectorFactoryBase(InDetDD::AthenaComps *athenaComps)
Dedicated detector manager extending the functionality of the SiDetectorManager with dedicated pixel ...
Helper class to concentrate common items, such as the pointer to the IdHelper, the lorentzAngle tool ...
Class to hold geometrical description of a silicon detector element.
Class to hold version information consisting of tag, name layout and description as strings,...
Definition Version.h:24
PixelDetectorFactory(PixelGeoModelAthenaComps *athenaComps, const PixelSwitches &switches)
virtual void create(GeoPhysVol *world)
InDetDD::PixelDetectorManager * m_detectorManager
virtual const InDetDD::PixelDetectorManager * getDetectorManager() const
std::unique_ptr< PixelGeometryManager > m_geometryManager
Class to hold various Athena components.
const PixelID * getIdHelper() const
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
size_type wafer_hash_max() const
Definition PixelID.cxx:801
bool dynamicAlignFolders() const
bool services() const
bool servicesOnLadder() const
bool initialLayout() const
bool dc1Geometry() const
bool dbm() const
bool ibl() const
bool alignable() const
std::string description
glabal timer - how long have I taken so far?
Definition hcg.cxx:91
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146
Message Stream Member.
@ timedependent_run2
MsgStream & msg
Definition testRead.cxx:32