ATLAS Offline Software
Loading...
Searching...
No Matches
PixelDetectorFactorySR1.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include "PixelSwitches.h"
8
9// Envelope, as a starting point of the geometry
10#include "GeoPixelBarrel.h"
11#include "GeoPixelEndCap.h"
12#include "GeoPixelServices.h"
13
14// GeoModel includes
15#include "GeoModelKernel/GeoNameTag.h"
16#include "GeoModelKernel/GeoIdentifierTag.h"
17#include "GeoModelKernel/GeoPhysVol.h"
18#include "GeoModelKernel/GeoAlignableTransform.h"
19#include "GaudiKernel/SystemOfUnits.h"
20
21// InDetReadoutGeometry
25
27#include "DBPixelGeoManager.h"
28
30
33
35 const PixelSwitches & switches)
36 : InDetDD::DetectorFactoryBase(athenaComps),
37 m_detectorManager(nullptr)
38{
39 // Create the detector manager
41
42 // Create the geometry manager.
43 m_geometryManager = new DBPixelGeoManager(athenaComps);
44
45 // Pass the switches
46 m_geometryManager->SetServices(switches.services());
47 m_geometryManager->SetServicesOnLadder(switches.servicesOnLadder()); //JBdV
48 m_geometryManager->SetDC1Geometry(switches.dc1Geometry());
49 m_geometryManager->SetAlignable(switches.alignable());
50 m_geometryManager->SetInitialLayout(switches.initialLayout());
51
52
53 // Create SiCommonItems ans store it in geometry manager.
54 // These are items that are shared by all elements
55 std::unique_ptr<SiCommonItems> commonItems{std::make_unique<SiCommonItems>(athenaComps->getIdHelper())};
56 m_geometryManager->setCommonItems(commonItems.get());
57
58 m_detectorManager->setCommonItems(std::move(commonItems));
59
60 // Determine if initial layer and tag from the id dict are consistent
61 bool initialLayoutIdDict = (m_detectorManager->tag() == "initial_layout");
62 if (m_geometryManager->InitialLayout() != initialLayoutIdDict ) {
63 if(msgLvl(MSG::WARNING))
64 msg(MSG::WARNING) << "IdDict tag is \"" << m_detectorManager->tag()
65 << "\" which is inconsistent with the layout choosen!"
66 << endmsg;
67 }
68
69
70 //
71 // Set Version information
72 //
73 std::string versionTag = m_geometryManager->versionTag();
74 std::string versionName = "SR1";
75 std::string layout = "SR1";
76 std::string description = "SR1 Geometry";
77 int versionMajorNumber = 4;
78 int versionMinorNumber = 0;
79 int versionPatchNumber = 0;
80
81 if (m_geometryManager->InitialLayout()) {
82 layout = "Initial";
83 }
84
85 InDetDD::Version version(versionTag,
86 versionName,
87 layout,
89 versionMajorNumber,
90 versionMinorNumber,
91 versionPatchNumber);
92 m_detectorManager->setVersion(version);
93
94}
95
96
101
102
103
104//## Other Operations (implementation)
105void PixelDetectorFactorySR1::create (GeoPhysVol *world)
106{
107 m_geometryManager->SetCurrentLD(0);
108 m_geometryManager->SetBarrel();
109 if(msgLvl(MSG::INFO)) {
110 msg(MSG::INFO) << "Building Pixel Detector" << endmsg;
111 msg(MSG::INFO) << " " << m_detectorManager->getVersion().fullDescription() << endmsg;
112
113 // Printout the parameters that are different in DC1 and DC2.
114 msg(MSG::INFO) << " B-Layer basic eta pitch: " << m_geometryManager->DesignPitchZ()/Gaudi::Units::micrometer << "um" << endmsg;
115 msg(MSG::INFO) << " B-Layer sensor thickness: " << m_geometryManager->PixelBoardThickness()/Gaudi::Units::micrometer << "um" << endmsg;
116 }
117
118 bool barrelPresent = m_geometryManager->partPresent("Barrel");
119 bool endcapAPresent = m_geometryManager->partPresent("EndcapA");
120 bool endcapCPresent = m_geometryManager->partPresent("EndcapC");
121
122 // Check that there is one and only one part built.
123 // Could have more than one part but then need to decide
124 // what to do about top level alignable transform.
125
126 if ((barrelPresent && endcapAPresent) ||
127 (barrelPresent && endcapCPresent) ||
128 (endcapAPresent && endcapCPresent)) {
129 msg(MSG::ERROR) << "SR1 geometry can only have 1 part" << endmsg;
130 }
131
132 if (!barrelPresent && !endcapAPresent && !endcapCPresent) {
133 msg(MSG::ERROR) << "SR1 geometry must have 1 part" << endmsg;
134 }
135
136 GeoVPhysVol* physVol = nullptr;
137 GeoAlignableTransform * transform = nullptr;
138
139 GeoPixelServices * pixServices = nullptr;
140 if(m_geometryManager->DoServices() ) {
141 pixServices = new GeoPixelServices(m_detectorManager, m_geometryManager, nullptr, nullptr, nullptr, nullptr);
142 }
143
144 // Top level transform
145 GeoTrf::Transform3D topTransform = m_geometryManager->partTransform("Pixel");
146
147 if (barrelPresent) {
148 //
149 // Add the Barrel:
150 //
151 m_geometryManager->SetBarrel();
152 GeoPixelBarrel brl(m_detectorManager, m_geometryManager, nullptr, nullptr, nullptr,pixServices);
153 physVol = brl.Build();
154
155 GeoTrf::Transform3D barrelTransform = m_geometryManager->partTransform("Barrel");
156 transform = new GeoAlignableTransform(topTransform*barrelTransform);
157
158 // Add this to the world
159 GeoNameTag* tag = new GeoNameTag("Pixel");
160 world->add(tag);
161 world->add(new GeoIdentifierTag(0));
162 world->add(physVol);
163 world->add(transform);
164
165 }
166
167 //
168 // Add the EndCaps
169 if (endcapAPresent || endcapCPresent) {
170 m_geometryManager->SetEndcap();
171
172 GeoPixelEndCap pec(m_detectorManager, m_geometryManager, nullptr, nullptr, nullptr, pixServices);
173 double zpos = (m_geometryManager->PixelEndcapZMax()+m_geometryManager->PixelEndcapZMin())/2.;
174
175
176 // EndCap A
177 if (endcapAPresent) {
178
179 m_geometryManager->SetPos();
180 physVol = pec.Build();
181
182 GeoTrf::Transform3D endcapATransform = m_geometryManager->partTransform("EndcapA");
183 transform = new GeoAlignableTransform(topTransform * endcapATransform * GeoTrf::TranslateZ3D(zpos));
184
185 GeoNameTag* tag = new GeoNameTag("Pixel");
186 world->add(tag);
187 world->add(new GeoIdentifierTag(2));
188 world->add(transform);
189 world->add(physVol);
190 }
191
192 // EndCap C
193 if (endcapCPresent) {
194
195 m_geometryManager->SetNeg();
196 physVol = pec.Build();
197
198 GeoTrf::Transform3D endcapCTransform = m_geometryManager->partTransform("EndcapC");
199 transform = new GeoAlignableTransform(topTransform * endcapCTransform * GeoTrf::TranslateZ3D(-zpos) * GeoTrf::RotateY3D(180*Gaudi::Units::deg));
200
201 GeoNameTag* tag = new GeoNameTag("Pixel");
202 world->add(tag);
203 world->add(new GeoIdentifierTag(-2));
204 world->add(transform);
205 world->add(physVol);
206 }
207
208 }
209
210 // Delete pixServices
211 if(pixServices) delete pixServices;
212
213 // Should not happen as we check before that we have at least one part built.
214 if (!physVol) {
215 msg(MSG::ERROR) << "Unexpected condition. Top level volume has zero pointer" << endmsg;
216 }
217
218 // Store alignable transform
219 Identifier id = m_geometryManager->getIdHelper()->wafer_id(0,0,0,0);
220 m_detectorManager->addAlignableTransform(2, id, transform, physVol);
221
222 //
223 // Add this to the list of top level physical volumes:
224 //
225 m_detectorManager->addTreeTop(physVol);
226
227 // Initialize the neighbours
228 m_detectorManager->initNeighbours();
229
230 // Set maximum rows/columns in numerology
231 for (int iDesign = 0; iDesign < m_detectorManager->numDesigns(); iDesign++) {
232 m_detectorManager->numerology().setMaxNumPhiCells(m_detectorManager->getPixelDesign(iDesign)->rows());
233 m_detectorManager->numerology().setMaxNumEtaCells(m_detectorManager->getPixelDesign(iDesign)->columns());
234 }
235
236 // Register the callbacks and keys and the level corresponding to the key.
237 if (m_geometryManager->Alignable()) {
238 m_detectorManager->addFolder("/Indet/Align");
239 m_detectorManager->addChannel("/Indet/Align/ID", 2, InDetDD::global);
240 m_detectorManager->addChannel("/Indet/Align/PIX", 1, InDetDD::global);
241 if (barrelPresent) {
242 m_detectorManager->addChannel("/Indet/Align/PIXB1", 0, InDetDD::local);
243 m_detectorManager->addChannel("/Indet/Align/PIXB2", 0, InDetDD::local);
244 m_detectorManager->addChannel("/Indet/Align/PIXB3", 0, InDetDD::local);
245 }
246 if (endcapAPresent) {
247 m_detectorManager->addChannel("/Indet/Align/PIXEA1", 0, InDetDD::local);
248 m_detectorManager->addChannel("/Indet/Align/PIXEA2", 0, InDetDD::local);
249 m_detectorManager->addChannel("/Indet/Align/PIXEA3", 0, InDetDD::local);
250 }
251 if (endcapCPresent) {
252 m_detectorManager->addChannel("/Indet/Align/PIXEC1", 0, InDetDD::local);
253 m_detectorManager->addChannel("/Indet/Align/PIXEC2", 0, InDetDD::local);
254 m_detectorManager->addChannel("/Indet/Align/PIXEC3", 0, InDetDD::local);
255 }
256 }
257}
258
263
#define endmsg
This is an Identifier helper class for the Pixel subdetector.
virtual GeoVPhysVol * Build() override
virtual GeoVPhysVol * Build() override
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 version information consisting of tag, name layout and description as strings,...
Definition Version.h:24
PixelDetectorFactorySR1(PixelGeoModelAthenaComps *athenaComps, const PixelSwitches &switches)
virtual void create(GeoPhysVol *world)
virtual const InDetDD::PixelDetectorManager * getDetectorManager() const
PixelGeometryManager * m_geometryManager
InDetDD::PixelDetectorManager * m_detectorManager
Class to hold various Athena components.
const PixelID * getIdHelper() const
bool services() const
bool servicesOnLadder() const
bool initialLayout() const
bool dc1Geometry() const
bool alignable() const
std::string description
glabal timer - how long have I taken so far?
Definition hcg.cxx:91
Message Stream Member.
MsgStream & msg
Definition testRead.cxx:32