ATLAS Offline Software
Loading...
Searching...
No Matches
GeometryBuilder.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// GeometryBuilder.cxx, (c) ATLAS Detector software
8
9// Trk include
15
16#ifdef TRKDETDESCR_MEMUSAGE
17#include <unistd.h>
18#endif
19
20// Amg
22// STD
23#include <map>
24// Gaudi
25#include "GaudiKernel/MsgStream.h"
26#include "GaudiKernel/SystemOfUnits.h"
27
28
29// constructor
30Trk::GeometryBuilder::GeometryBuilder(const std::string& t, const std::string& n, const IInterface* p)
31: AthAlgTool(t,n,p),
33{
34 declareInterface<IGeometryBuilder>(this);
35}
36
37
38// Athena standard methods
39// initialize
41{
42
43 // Retrieve the volume array creator ----------------------------------------------------
45
46 // Retrieve the tracking volume helper --------------------------------------------------
48 // Geometries =============================================================================
49 // (I) Inner Detector ---------------------------------------------------------------------
50 if (!m_inDetGeometryBuilder.empty()) {
52 }
53 // (C) Calorimeter --------------------------------------------------------------------------
54 if (!m_caloGeometryBuilder.empty()) {
56 }
57 // (M) Muon System -------------------------------------------------------------------------
58 if (!m_muonGeometryBuilder.empty()) {
60 }
61
62 // if no world dimensions are declared, take default ones
63 if (m_worldDimension.empty())
64 m_worldDimension = std::vector<double>{0.*Gaudi::Units::meter, 10.*Gaudi::Units::meter, 15.*Gaudi::Units::meter};
65
66 // if no world materials are declared, take default ones - set vacuum
67 if (m_worldMaterialProperties.size() < 5)
68 m_worldMaterialProperties = std::vector<double>{10.e10,10.e10,0., 0., 0.};
69
75
76 ATH_MSG_DEBUG( " initialize() successful" );
77
78 return StatusCode::SUCCESS;
79}
80
81
82std::unique_ptr<Trk::TrackingGeometry> Trk::GeometryBuilder::trackingGeometry(Trk::TrackingVolume*) const
83{
84
85 // the geometry to be constructed
86 std::unique_ptr<Trk::TrackingGeometry> tGeometry = nullptr;
87 if ( m_inDetGeometryBuilder.empty() && m_caloGeometryBuilder.empty() && m_muonGeometryBuilder.empty() ) {
88
89 ATH_MSG_VERBOSE( "Configured to only create world TrackingVolume." );
90
91 auto worldBounds = std::make_shared<Trk::CylinderVolumeBounds>(m_worldDimension[0],
94
95 Trk::TrackingVolume* worldVolume = new Trk::TrackingVolume(nullptr,
96 std::move(worldBounds),
98 nullptr,
99 nullptr,
100 "EmptyWorldVolume");
101
102 // create a new geometry
103 tGeometry = std::make_unique<Trk::TrackingGeometry>(worldVolume);
104 } else
105 tGeometry = atlasTrackingGeometry();
106 // sign it before you return anything
107 tGeometry->sign(geometrySignature());
108 return tGeometry;
109
110}
111
112
113std::unique_ptr<Trk::TrackingGeometry> Trk::GeometryBuilder::atlasTrackingGeometry() const
114{
115 // the return geometry
116 std::unique_ptr<Trk::TrackingGeometry> atlasTrackingGeometry = nullptr;
117
118 // A ------------- INNER DETECTOR SECTION --------------------------------------------------------------------------------
119 // get the Inner Detector and/or Calorimeter trackingGeometry
120 std::unique_ptr<Trk::TrackingGeometry> inDetTrackingGeometry = nullptr;
121 std::unique_ptr<Trk::TrackingGeometry> caloTrackingGeometry = nullptr;
122
123 // the volumes to be given to higher level tracking geometry builders
124 Trk::TrackingVolume* inDetVolume = nullptr;
125 Trk::TrackingVolume* caloVolume = nullptr;
126
127 // mark the highest volume
128 Trk::TrackingVolume* highestVolume = nullptr;
129
130#ifdef TRKDETDESCR_MEMUSAGE
131 m_memoryLogger.refresh(getpid());
132 ATH_MSG_INFO( "[ memory usage ] Start of TrackingGeometry building: " );
133 ATH_MSG_INFO( m_memoryLogger );
134#endif
135
136 // ========================== INNER DETECTOR PART =================================================
137 if (!m_inDetGeometryBuilder.empty()) {
138 // debug output
139 ATH_MSG_VERBOSE( "ID Tracking Geometry is going to be built." );
140 // build the geometry
141 inDetTrackingGeometry = m_inDetGeometryBuilder->trackingGeometry();
142 // check
143 if (inDetTrackingGeometry) {
144 // sign it
145 inDetTrackingGeometry->sign(m_inDetGeometryBuilder->geometrySignature());
146 // check whether the world has to be created or not
147 if (m_createWorld) {
148 // checkout the highest InDet volume
149 inDetVolume = inDetTrackingGeometry->checkoutHighestTrackingVolume();
150 // assign it as the highest volume
151 highestVolume = inDetVolume;
152 } else // -> Take the exit and return ID stand alone
153 atlasTrackingGeometry = std::move(inDetTrackingGeometry);
154 }
155
156#ifdef TRKDETDESCR_MEMUSAGE
157 m_memoryLogger.refresh(getpid());
158 ATH_MSG_INFO( "[ memory usage ] After InDet TrackingGeometry building: " );
159 ATH_MSG_INFO( m_memoryLogger );
160#endif
161
162 }
163
164 // ========================== CALORIMETER PART =================================================
165 // if a Calo Geometry Builder is present -> wrap it around the ID
166 if (!m_caloGeometryBuilder.empty()) {
167 if (inDetVolume)
168 ATH_MSG_VERBOSE( "Calorimeter Tracking Geometry is going to be built with enclosed ID." );
169 else
170 ATH_MSG_VERBOSE( "Calorimeter Tracking Geometry is going to be built stand-alone." );
171 // get the InnerDetector TrackingGeometry
172 caloTrackingGeometry = m_caloGeometryBuilder->trackingGeometry(inDetVolume);
173 // if you have to create world or there is a Muon geometry builder ...
174 if (caloTrackingGeometry) {
175 // sign it
176 caloTrackingGeometry->sign(m_caloGeometryBuilder->geometrySignature());
177 if (m_createWorld){
178 // check out the highest Calo volume
179 caloVolume = caloTrackingGeometry->checkoutHighestTrackingVolume();
180 // assign it as the highest volume (overwrite ID)
181 highestVolume = caloVolume;
182 } else // -> Take the exit and return Calo back
183 atlasTrackingGeometry = std::move(caloTrackingGeometry);
184 }
185
186#ifdef TRKDETDESCR_MEMUSAGE
187 m_memoryLogger.refresh(getpid());
188 ATH_MSG_INFO( "[ memory usage ] After Calo TrackingGeometry building: " );
189 ATH_MSG_INFO( m_memoryLogger );
190#endif
191
192 }
193
194 // ========================== MUON SYSTEM PART =================================================
195 // if Muon Geometry Builder is present -> wrap either ID or Calo
196 if (!m_muonGeometryBuilder.empty()) {
197
198 std::string enclosed = "stand-alone.";
199 if (inDetVolume && caloVolume)
200 enclosed = "with encloded ID/Calo.";
201 else if (inDetVolume || caloVolume)
202 enclosed = (inDetVolume) ? "with encloded ID." : "with encloded Calo.";
203 ATH_MSG_VERBOSE( "Muon System Tracking Geometry is going to be built "<< enclosed );
204 // there's nothing outside the muons -- wrap the calo if it exists
205 if (inDetVolume && !caloVolume)
206 atlasTrackingGeometry = m_muonGeometryBuilder->trackingGeometry( inDetVolume );
207 else
208 atlasTrackingGeometry = m_muonGeometryBuilder->trackingGeometry( caloVolume );
209
210 // sign it
212 atlasTrackingGeometry->sign(m_muonGeometryBuilder->geometrySignature());
213
214#ifdef TRKDETDESCR_MEMUSAGE
215 m_memoryLogger.refresh(getpid());
216 ATH_MSG_INFO( "[ memory usage ] After Muon TrackingGeometry building: " );
217 ATH_MSG_INFO( m_memoryLogger );
218#endif
219
220 // ========================== WRAPPING SECTION FOR ID/CALO ====================================
221 } else if (m_createWorld && highestVolume) {
222 // wrapping and world creation has been switched on
223 ATH_MSG_VERBOSE( "Enclosing world is going to be built for: " << highestVolume->volumeName() );
224 // get the glue volumes
225 Trk::GlueVolumesDescriptor& innerGlueVolumes = highestVolume->glueVolumesDescriptor();
226 // some screen output
227 ATH_MSG_VERBOSE( "Retrieved with following glue volumes: " << innerGlueVolumes );
228 // at negative face
229 const std::vector<Trk::TrackingVolume*>& innerNegativeFaceVolumes = innerGlueVolumes.glueVolumes(Trk::negativeFaceXY);
230 // at cylinder cover
231 const std::vector<Trk::TrackingVolume*>& innerCentralFaceVolumes = innerGlueVolumes.glueVolumes(Trk::cylinderCover);
232 // at positive face
233 const std::vector<Trk::TrackingVolume*>& innerPositiveFaceVolumes = innerGlueVolumes.glueVolumes(Trk::positiveFaceXY);
234
235 // get the dimensions
236 // cast them to CylinderVolumeBounds
237 const Trk::CylinderVolumeBounds* innerVolumeBounds = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(highestVolume->volumeBounds()));
238 if (!innerVolumeBounds) ATH_MSG_WARNING( "atlasTrackingGeometry() ... dynamic cast to innerVolumeBounds failed!" );
239 double innerVolumeOuterR = innerVolumeBounds ? innerVolumeBounds->outerRadius() : 0;
240 double innerVolumeHalflengthZ = innerVolumeBounds ? innerVolumeBounds->halflengthZ() : 0;
241 // Hierarchy after enclosing
242 //
243 // AtlasWorldVolume:
244 // AtlasInnerCylinder
245 // AtlasInnerNegativeSector
246 // InnerEnclosedVolume (can be ID/Calo)
247 // AtlasOuterNegativeSector
248 // AtlasOuterTube
249 // B -------------- BUILD WORLD AROUND for ID stand alone applications
250
251 double innerCylinderSectorHalflengthZ = 0.5*(m_worldDimension[2] - innerVolumeHalflengthZ);
252 auto innerCylinderSectorBounds =
253 std::make_shared<Trk::CylinderVolumeBounds>(0., innerVolumeOuterR, innerCylinderSectorHalflengthZ);
254
255 double innerCylinderSectorPositionZ = fabs(m_worldDimension[2]-innerCylinderSectorHalflengthZ);
256
257 // the AtlasInnerNegativeSector
258 auto atlasInnerNegativeSectorTransf = std::make_unique<Amg::Transform3D>(Amg::Translation3D(0.,0.,-innerCylinderSectorPositionZ));
259 Trk::TrackingVolume* atlasInnerNegativeSector = new Trk::TrackingVolume(
260 std::move(atlasInnerNegativeSectorTransf),
261 std::make_shared<Trk::CylinderVolumeBounds>(*innerCylinderSectorBounds),
263 nullptr,
264 nullptr,
265 "AtlasInnerNegativeSector");
266
267 // the AtlasInnerPositiveSector
268 auto atlasInnerPositiveSectorTransf = std::make_unique<Amg::Transform3D>(Amg::Translation3D(0.,0.,innerCylinderSectorPositionZ));
269 Trk::TrackingVolume* atlasInnerPositiveSector = new Trk::TrackingVolume(
270 std::move(atlasInnerPositiveSectorTransf),
271 std::move(innerCylinderSectorBounds),
273 nullptr,
274 nullptr,
275 "AtlasInnerPositiveSector");
276
277 ATH_MSG_VERBOSE( "Inner Negative/Positive Sectors built successfully." );
278
279 // create the subvolume Array
280 auto atlasInnerSectorVolumes = std::vector<Trk::TrackingVolume*>{atlasInnerNegativeSector,highestVolume,atlasInnerPositiveSector};
281
282 ATH_MSG_VERBOSE( "Create the Atlas Inner Sector volumes. " );
283 std::unique_ptr<Trk::BinnedArray<Trk::TrackingVolume>>
284 atlasInnerSectorVolumeArray =
286 ? m_trackingVolumeArrayCreator->cylinderVolumesArrayInZ(atlasInnerSectorVolumes)
287 : nullptr;
288
289 // Atlas inner Sector bounds
290 auto innerSectorBounds =
291 std::make_shared<Trk::CylinderVolumeBounds>(0., innerVolumeOuterR, m_worldDimension[2]);
292 // build the Tracking volumes
293 Trk::TrackingVolume* atlasInnerSector = new Trk::TrackingVolume(nullptr,
294 std::move(innerSectorBounds),
296 nullptr,
297 std::move(atlasInnerSectorVolumeArray),
298 "AtlasInnerSector");
299
300 // Atlas outer Sector
301 auto outerSectorBounds =
302 std::make_shared<Trk::CylinderVolumeBounds>(innerVolumeOuterR, m_worldDimension[1], m_worldDimension[2]);
303 Trk::TrackingVolume* atlasOuterSector = new Trk::TrackingVolume(nullptr,
304 std::move(outerSectorBounds),
306 nullptr,
307 nullptr,
308 "AtlasOuterSector");
309
310 ATH_MSG_VERBOSE( "Atlas Inner/Outer Sectors built successfully." );
311
312 // create the array of Inner and Outer sector
313 auto atlasVolumes = std::vector<Trk::TrackingVolume*>{atlasInnerSector, atlasOuterSector};
314
315 std::unique_ptr<Trk::BinnedArray<Trk::TrackingVolume>>
316 atlasVolumeArray =
318 ? m_trackingVolumeArrayCreator->cylinderVolumesArrayInR(atlasVolumes)
319 : nullptr;
320
321 // create the Atlas volume bounds
322 auto atlasBounds = std::make_shared<Trk::CylinderVolumeBounds>(0., m_worldDimension[1], m_worldDimension[2]);
323
324 // create the Atlas TrackingVolume
325 Trk::TrackingVolume* atlasVolume = new Trk::TrackingVolume(nullptr,
326 std::move(atlasBounds),
328 nullptr,
329 std::move(atlasVolumeArray),
330 "Atlas");
331
332 ATH_MSG_VERBOSE( "Atlas Tracking World volume built successfully." );
333
334
335 // glue the inner sector to be complete
336 m_trackingVolumeHelper->glueTrackingVolumes( *atlasInnerNegativeSector, Trk::positiveFaceXY,
337 innerNegativeFaceVolumes, Trk::negativeFaceXY );
338
339 m_trackingVolumeHelper->glueTrackingVolumes( *atlasInnerPositiveSector, Trk::negativeFaceXY,
340 innerPositiveFaceVolumes, Trk::positiveFaceXY );
341
342 ATH_MSG_VERBOSE( "Atlas Inner Sector glued successfully together." );
343
344 // iterators to the face volumes
345 auto volIter = innerCentralFaceVolumes.begin();
346 auto volIterEnd = innerCentralFaceVolumes.end();
347
348 // glue outer and inner sector together
349 std::vector<Trk::TrackingVolume*> atlasInnerOuterVolumes;
350 atlasInnerOuterVolumes.push_back(atlasInnerNegativeSector);
351 for (; volIter != volIterEnd; ++volIter) {
352 if (*volIter) {
353 atlasInnerOuterVolumes.push_back(*volIter);
354 }
355 }
356 atlasInnerOuterVolumes.push_back(atlasInnerPositiveSector);
357
358 m_trackingVolumeHelper->glueTrackingVolumes(*atlasOuterSector, Trk::tubeInnerCover,
359 atlasInnerOuterVolumes, Trk::tubeOuterCover);
360
361 ATH_MSG_VERBOSE( "Atlas Inner/Outer Sector glued successfully together." );
362
363 // job done -> create the TrackingGeometry
364 atlasTrackingGeometry = std::make_unique<Trk::TrackingGeometry>(atlasVolume);
365
366 // detailed information about this tracking geometry
367 ATH_MSG_VERBOSE( "Atlas TrackingGeometry built with following parameters : ");
368 //ATH_MSG_VERBOSE( " - TrackingVolume containers : " << atlasTrackingGeometry->numberOfContainerVolumes() );
369 //ATH_MSG_VERBOSE( " - TrackingVolume at navigation level : " << atlasTrackingGeometry->numberOfContainerVolumes() );
370 //ATH_MSG_VERBOSE( " - Contained static layers : " << atlasTrackingGeometry->boundaryLayers().size());
371 ATH_MSG_VERBOSE( " - Unique material layers on boundaries : " << atlasTrackingGeometry->boundaryLayers().size());
372
373#ifdef TRKDETDESCR_MEMUSAGE
374 m_memoryLogger.refresh(getpid());
375 ATH_MSG_INFO( "[ memory usage ] After Outer Sector TrackingGeometry building: " );
376 ATH_MSG_INFO( m_memoryLogger );
377#endif
378
379 }
380
382 if (m_navigationLevel < 3)
383 atlasTrackingGeometry->registerNavigationLevel( Trk::NavigationLevel(m_navigationLevel.value()));
384 }
385 else ATH_MSG_WARNING( "atlasTrackingGeometry() ... atlasTrackingGeometry = 0, could not call registerNavigationLevel and propagateMagneticFieldProperties" );
386
387#ifdef TRKDETDESCR_MEMUSAGE
388 m_memoryLogger.refresh(getpid());
389 ATH_MSG_INFO( "[ memory usage ] End of TrackingGeometry building: " );
390 ATH_MSG_INFO( m_memoryLogger );
391#endif
392
393 // synchronize the layers
395 if (m_synchronizeLayers) atlasTrackingGeometry->synchronizeLayers(msg());
396
397 // compactify if configured to do so
398 if (m_compactify) atlasTrackingGeometry->compactify(msg());
399 }
401}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Bounds for a cylindrical Volume, the decomposeToSurfaces method creates a vector of up to 6 surfaces:
double halflengthZ() const
This method returns the halflengthZ.
double outerRadius() const
This method returns the outer radius.
StatusCode initialize()
AlgTool initialize method.
GeometrySignature geometrySignature() const
The unique signature.
ToolHandle< ITrackingVolumeHelper > m_trackingVolumeHelper
ToolHandle< IGeometryBuilder > m_muonGeometryBuilder
Gaudi::Property< std::vector< double > > m_worldDimension
ToolHandle< IGeometryBuilder > m_inDetGeometryBuilder
std::unique_ptr< TrackingGeometry > trackingGeometry(TrackingVolume *tvol=0) const
TrackingGeometry Interface method - optionally a pointer to Bounds.
Gaudi::Property< bool > m_createWorld
GeometryBuilder(const std::string &, const std::string &, const IInterface *)
Constructor.
Gaudi::Property< int > m_navigationLevel
ToolHandle< IGeometryBuilder > m_caloGeometryBuilder
Gaudi::Property< bool > m_synchronizeLayers
Gaudi::Property< bool > m_compactify
Gaudi::Property< std::vector< double > > m_worldMaterialProperties
std::unique_ptr< TrackingGeometry > atlasTrackingGeometry() const
TrackingGeometry for ATLAS setup.
ToolHandle< ITrackingVolumeArrayCreator > m_trackingVolumeArrayCreator
Material m_worldMaterial
the world material
Descriptor class to hold GlueVolumes of a TrackingGeometry object.
const std::vector< TrackingVolume * > & glueVolumes(BoundarySurfaceFace)
retrieve them again
A common object to be contained by.
Definition Material.h:117
Full Volume description used in Tracking, it inherits from Volume to get the geometrical structure,...
const std::string & volumeName() const
Returns the VolumeName - for debug reason, might be depreciated later.
GlueVolumesDescriptor & glueVolumesDescriptor()
const VolumeBounds & volumeBounds() const
returns the volumeBounds()
Definition Volume.h:96
Eigen::Translation< double, 3 > Translation3D
NavigationLevel
destinguishes an association TrackingGeometry with one for global search
MsgStream & msg
Definition testRead.cxx:32