ATLAS Offline Software
Loading...
Searching...
No Matches
GeometryBuilderCond.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// GeometryBuilderCond.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//Athena
26// Gaudi
27#include "GaudiKernel/MsgStream.h"
28#include "GaudiKernel/SystemOfUnits.h"
29
30
31// constructor
32Trk::GeometryBuilderCond::GeometryBuilderCond(const std::string& t, const std::string& n, const IInterface* p)
33: AthAlgTool(t,n,p),
35{
36 declareInterface<IGeometryBuilderCond>(this);
37}
38
39
40// Athena standard methods
41// initialize
43{
44
45 // Retrieve the volume array creator ----------------------------------------------------
47
48 // Retrieve the tracking volume helper --------------------------------------------------
50 // Geometries =============================================================================
51 // (I) Inner Detector ---------------------------------------------------------------------
52 if (!m_inDetGeometryBuilderCond.empty()) {
54 }
55 // (H) High Granularity Timing Detector ----------------------------------------------------
56 if(!m_hgtdGeometryBuilderCond.empty()) {
57 if (m_hgtdGeometryBuilderCond.retrieve().isFailure()) {
58 ATH_MSG_FATAL("Failed to retrieve tool " << m_hgtdGeometryBuilderCond );
59 return StatusCode::FAILURE;
60 } else
61 ATH_MSG_INFO( "Retrieved tool " << m_hgtdGeometryBuilderCond );
62 }
63 // (C) Calorimeter --------------------------------------------------------------------------
64 if (!m_caloGeometryBuilderCond.empty()) {
66 }
67 // (M) Muon System -------------------------------------------------------------------------
68 if (!m_muonGeometryBuilderCond.empty()) {
70 }
71
72 // if no world dimensions are declared, take default ones
73 if (m_worldDimension.empty())
74 m_worldDimension = std::vector<double>{0.*Gaudi::Units::meter, 10.*Gaudi::Units::meter, 15.*Gaudi::Units::meter};
75
76 // if no world materials are declared, take default ones - set vacuum
77 if (m_worldMaterialProperties.size() < 5)
78 m_worldMaterialProperties = std::vector<double>{10.e10,10.e10,1e-10, 0., 0.};
79
85
86 ATH_MSG_DEBUG( " initialize() successful" );
87
88 return StatusCode::SUCCESS;
89}
90
91std::unique_ptr< Trk::TrackingGeometry>
93 Trk::TrackingVolume* /*tVol*/,
95{
96
97 // the geometry to be constructed
98 std::unique_ptr<Trk::TrackingGeometry> tGeometry;
100
101 ATH_MSG_VERBOSE( "Configured to only create world TrackingVolume." );
102
103 auto worldBounds = std::make_shared<Trk::CylinderVolumeBounds>(m_worldDimension[0],
106
107 Trk::TrackingVolume* worldVolume = new Trk::TrackingVolume(nullptr,
108 worldBounds,
110 nullptr,
111 nullptr,
112 "EmptyWorldVolume");
113 // create a new geometry
114 tGeometry = std::make_unique<Trk::TrackingGeometry>(worldVolume);
115 } else
116 tGeometry = atlasTrackingGeometry(ctx, whandle);
117 // sign it before you return anything
118 tGeometry->sign(geometrySignature());
119 return tGeometry;
120}
121
122
123std::unique_ptr<Trk::TrackingGeometry>
126{
127 // the return geometry
128 std::unique_ptr<Trk::TrackingGeometry> atlasTrackingGeometry;
129
130 // A ------------- INNER DETECTOR SECTION --------------------------------------------------------------------------------
131 // get the Inner Detector and/or HGTD and/or Calorimeter trackingGeometry
132
133 // the volumes to be given to higher level tracking geometry builders
134 Trk::TrackingVolume* inDetVolume = nullptr;
135 Trk::TrackingVolume* hgtdVolume = nullptr;
136 Trk::TrackingVolume* caloVolume = nullptr;
137
138 // mark the highest volume
139 Trk::TrackingVolume* highestVolume = nullptr;
140
141#ifdef TRKDETDESCR_MEMUSAGE
142 m_memoryLogger.refresh(getpid());
143 ATH_MSG_INFO( "[ memory usage ] Start of TrackingGeometry building: " );
144 ATH_MSG_INFO( m_memoryLogger );
145#endif
146
147 // ========================== INNER DETECTOR PART =================================================
148 if (!m_inDetGeometryBuilderCond.empty()) {
149 // debug output
150 ATH_MSG_VERBOSE( "ID Tracking Geometry is going to be built." );
151 // build the geometry
152 std::unique_ptr<Trk::TrackingGeometry> inDetTrackingGeometry =
153 m_inDetGeometryBuilderCond->trackingGeometry(ctx, nullptr, whandle);
154 // check
155 if (inDetTrackingGeometry) {
156 // sign it
157 inDetTrackingGeometry->sign(m_inDetGeometryBuilderCond->geometrySignature());
158 // check whether the world has to be created or not
159 if (m_createWorld) {
160 // checkout the highest InDet volume
161 inDetVolume = inDetTrackingGeometry->checkoutHighestTrackingVolume();
162 // assign it as the highest volume
163 highestVolume = inDetVolume;
164 } else // -> Take the exit and return ID stand alone
165 atlasTrackingGeometry = std::move(inDetTrackingGeometry);
166 }
167
168#ifdef TRKDETDESCR_MEMUSAGE
169 m_memoryLogger.refresh(getpid());
170 ATH_MSG_INFO( "[ memory usage ] After InDet TrackingGeometry building: " );
171 ATH_MSG_INFO( m_memoryLogger );
172#endif
173
174 }
175
176 // ========================== HGTD PART =================================================
177 // if a HGTD Geometry Builder is present -> wrap it around the ID
178 if (!m_hgtdGeometryBuilderCond.empty()) {
179 if (inDetVolume)
180 ATH_MSG_VERBOSE( "HGTD Tracking Geometry is going to be built with enclosed ID." );
181 else
182 ATH_MSG_VERBOSE( "HGTD Tracking Geometry is going to be built stand-alone." );
183 // get the InnerDetector TrackingGeometry
184 std::unique_ptr<Trk::TrackingGeometry> hgtdTrackingGeometry =
185 m_hgtdGeometryBuilderCond->trackingGeometry(ctx, inDetVolume, whandle);
186 // if you have to create world or there is a Calo/Muon geometry builder ...
187 if (hgtdTrackingGeometry) {
188 // sign it
189 hgtdTrackingGeometry->sign(m_hgtdGeometryBuilderCond->geometrySignature());
190 if (m_createWorld){
191 // check out the highest Calo volume
192 hgtdVolume = hgtdTrackingGeometry->checkoutHighestTrackingVolume();
193 // assign it as the highest volume (overwrite ID)
194 highestVolume = hgtdVolume;
195 } else // -> Take the exit and return HGTD back
196 atlasTrackingGeometry = std::move(hgtdTrackingGeometry);
197 }
198
199#ifdef TRKDETDESCR_MEMUSAGE
200 m_memoryLogger.refresh(getpid());
201 ATH_MSG_INFO( "[ memory usage ] After Calo TrackingGeometry building: " );
202 ATH_MSG_INFO( m_memoryLogger );
203#endif
204
205 }
206
207 // ========================== CALORIMETER PART =================================================
208 // if a Calo Geometry Builder is present -> wrap it around the ID or HGTD
209 if (!m_caloGeometryBuilderCond.empty()) {
210 std::string enclosed = "stand-alone.";
211 if (inDetVolume and hgtdVolume)
212 enclosed = "with encloded ID/HGTD.";
213 else if (inDetVolume or hgtdVolume)
214 enclosed = (inDetVolume) ? "with encloded ID." : "with encloded HGTD.";
215 ATH_MSG_VERBOSE( "Calorimeter Tracking Geometry is going to be built "<< enclosed );
216
217 // get the InnerDetector TrackingGeometry or the HGTD tracking geometry
218 std::unique_ptr<Trk::TrackingGeometry> caloTrackingGeometry;
219 if (inDetVolume and not hgtdVolume)
220 caloTrackingGeometry = m_caloGeometryBuilderCond->trackingGeometry(ctx, inDetVolume, whandle);
221 else
222 caloTrackingGeometry = m_caloGeometryBuilderCond->trackingGeometry(ctx, hgtdVolume, whandle);
223 // if you have to create world or there is a Muon geometry builder ...
224 if (caloTrackingGeometry) {
225 // sign it
226 caloTrackingGeometry->sign(m_caloGeometryBuilderCond->geometrySignature());
227 if (m_createWorld){
228 // check out the highest Calo volume
229 caloVolume = caloTrackingGeometry->checkoutHighestTrackingVolume();
230 // assign it as the highest volume (overwrite ID)
231 highestVolume = caloVolume;
232 } else // -> Take the exit and return Calo back
233 atlasTrackingGeometry = std::move(caloTrackingGeometry);
234 }
235
236#ifdef TRKDETDESCR_MEMUSAGE
237 m_memoryLogger.refresh(getpid());
238 ATH_MSG_INFO( "[ memory usage ] After Calo TrackingGeometry building: " );
239 ATH_MSG_INFO( m_memoryLogger );
240#endif
241
242 }
243
244 // ========================== MUON SYSTEM PART =================================================
245 // if Muon Geometry Builder is present -> wrap either ID or Calo
246 if (!m_muonGeometryBuilderCond.empty()) {
247 std::string enclosed = "stand-alone.";
248 if (inDetVolume and hgtdVolume and caloVolume )
249 enclosed = "with encloded ID/HGTD/Calo.";
250 else if (inDetVolume or hgtdVolume or caloVolume) {
251 if (inDetVolume) {
252 if (hgtdVolume)
253 enclosed = "with encloded ID/HGTD";
254 else if (caloVolume)
255 enclosed = "with encloded ID/Calo";
256 else
257 enclosed = "with encloded ID";
258 } else if (hgtdVolume) {
259 if (caloVolume)
260 enclosed = "with encloded HGTD/Calo";
261 else
262 enclosed = "with encloded HGTD";
263 } else {
264 enclosed = "with encloded Calo";
265 }
266 }
267 ATH_MSG_VERBOSE( "Muon System Tracking Geometry is going to be built "<< enclosed );
268
269 // there's nothing outside the muons -- wrap the calo or the HGTD if one or both of them exist
270 if (inDetVolume and not hgtdVolume and not caloVolume)
271 atlasTrackingGeometry = m_muonGeometryBuilderCond->trackingGeometry(ctx, inDetVolume, whandle);
272 else if (hgtdVolume and not caloVolume)
273 atlasTrackingGeometry = m_muonGeometryBuilderCond->trackingGeometry(ctx, hgtdVolume, whandle);
274 else
275 atlasTrackingGeometry = m_muonGeometryBuilderCond->trackingGeometry(ctx, caloVolume, whandle);
276
277 // sign it
279 atlasTrackingGeometry->sign(m_muonGeometryBuilderCond->geometrySignature());
280
281#ifdef TRKDETDESCR_MEMUSAGE
282 m_memoryLogger.refresh(getpid());
283 ATH_MSG_INFO( "[ memory usage ] After Muon TrackingGeometry building: " );
284 ATH_MSG_INFO( m_memoryLogger );
285#endif
286
287 // ========================== WRAPPING SECTION FOR ID/CALO ====================================
288 } else if (m_createWorld && highestVolume) {
289 // wrapping and world creation has been switched on
290 ATH_MSG_VERBOSE( "Enclosing world is going to be built for: " << highestVolume->volumeName() );
291 // get the glue volumes
292 Trk::GlueVolumesDescriptor& innerGlueVolumes = highestVolume->glueVolumesDescriptor();
293 // some screen output
294 ATH_MSG_VERBOSE( "Retrieved with following glue volumes: " << innerGlueVolumes );
295 // at negative face
296 const std::vector<Trk::TrackingVolume*>& innerNegativeFaceVolumes = innerGlueVolumes.glueVolumes(Trk::negativeFaceXY);
297 // at cylinder cover
298 const std::vector<Trk::TrackingVolume*>& innerCentralFaceVolumes = innerGlueVolumes.glueVolumes(Trk::cylinderCover);
299 // at positive face
300 const std::vector<Trk::TrackingVolume*>& innerPositiveFaceVolumes = innerGlueVolumes.glueVolumes(Trk::positiveFaceXY);
301
302 // get the dimensions
303 // cast them to CylinderVolumeBounds
304 const Trk::CylinderVolumeBounds* innerVolumeBounds = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(highestVolume->volumeBounds()));
305 if (!innerVolumeBounds) ATH_MSG_WARNING( "atlasTrackingGeometry() ... dynamic cast to innerVolumeBounds failed!" );
306 double innerVolumeOuterR = innerVolumeBounds ? innerVolumeBounds->outerRadius() : 0;
307 double innerVolumeHalflengthZ = innerVolumeBounds ? innerVolumeBounds->halflengthZ() : 0;
308 // Hierarchy after enclosing
309 //
310 // AtlasWorldVolume:
311 // AtlasInnerCylinder
312 // AtlasInnerNegativeSector
313 // InnerEnclosedVolume (can be ID/Calo)
314 // AtlasOuterNegativeSector
315 // AtlasOuterTube
316 // B -------------- BUILD WORLD AROUND for ID stand alone applications
317
318 double innerCylinderSectorHalflengthZ = 0.5*(m_worldDimension[2] - innerVolumeHalflengthZ);
319 auto innerCylinderSectorBounds = std::make_shared<Trk::CylinderVolumeBounds>(0., innerVolumeOuterR, innerCylinderSectorHalflengthZ);
320
321 double innerCylinderSectorPositionZ = fabs(m_worldDimension[2]-innerCylinderSectorHalflengthZ);
322
323 // the AtlasInnerNegativeSector
324 auto atlasInnerNegativeSectorTransf = std::make_unique<Amg::Transform3D>(Amg::Translation3D(0.,0.,-innerCylinderSectorPositionZ));
325 Trk::TrackingVolume* atlasInnerNegativeSector = new Trk::TrackingVolume(
326 std::move(atlasInnerNegativeSectorTransf),
327 innerCylinderSectorBounds,
329 nullptr,
330 nullptr,
331 "AtlasInnerNegativeSector");
332
333 // the AtlasInnerPositiveSector
334 auto atlasInnerPositiveSectorTransf = std::make_unique<Amg::Transform3D>(Amg::Translation3D(0.,0.,innerCylinderSectorPositionZ));
335 Trk::TrackingVolume* atlasInnerPositiveSector = new Trk::TrackingVolume(
336 std::move(atlasInnerPositiveSectorTransf),
337 std::make_shared<Trk::CylinderVolumeBounds>(*innerCylinderSectorBounds),
339 nullptr,
340 nullptr,
341 "AtlasInnerPositiveSector");
342
343 ATH_MSG_VERBOSE( "Inner Negative/Positive Sectors built successfully." );
344
345 // create the subvolume Array
346 auto atlasInnerSectorVolumes = std::vector<Trk::TrackingVolume*>{atlasInnerNegativeSector,highestVolume,atlasInnerPositiveSector};
347
348 ATH_MSG_VERBOSE( "Create the Atlas Inner Sector volumes. " );
349 std::unique_ptr<Trk::BinnedArray<Trk::TrackingVolume>> atlasInnerSectorVolumeArray = m_trackingVolumeArrayCreator ?
350 m_trackingVolumeArrayCreator->cylinderVolumesArrayInZ(atlasInnerSectorVolumes) : nullptr;
351
352
353 // Atlas inner Sector bounds
354 auto innerSectorBounds =
355 std::make_shared<Trk::CylinderVolumeBounds>(0., innerVolumeOuterR, m_worldDimension[2]);
356 // build the Tracking volumes
357 Trk::TrackingVolume* atlasInnerSector = new Trk::TrackingVolume(nullptr,
358 innerSectorBounds,
360 nullptr,
361 std::move(atlasInnerSectorVolumeArray),
362 "AtlasInnerSector");
363
364 // Atlas outer Sector
365 auto outerSectorBounds =
366 std::make_shared<Trk::CylinderVolumeBounds>(innerVolumeOuterR, m_worldDimension[1], m_worldDimension[2]);
367 Trk::TrackingVolume* atlasOuterSector = new Trk::TrackingVolume(nullptr,
368 outerSectorBounds,
370 nullptr,
371 nullptr,
372 "AtlasOuterSector");
373
374 ATH_MSG_VERBOSE( "Atlas Inner/Outer Sectors built successfully." );
375
376 // create the array of Inner and Outer sector
377 auto atlasVolumes = std::vector<Trk::TrackingVolume*>{atlasInnerSector, atlasOuterSector};
378
379 std::unique_ptr<Trk::BinnedArray<Trk::TrackingVolume>> atlasVolumeArray = m_trackingVolumeArrayCreator ?
380 m_trackingVolumeArrayCreator->cylinderVolumesArrayInR(atlasVolumes) : nullptr;
381
382 // create the Atlas volume bounds
383 auto atlasBounds = std::make_shared<Trk::CylinderVolumeBounds>(0., m_worldDimension[1], m_worldDimension[2]);
384
385 // create the Atlas TrackingVolume
386 Trk::TrackingVolume* atlasVolume = new Trk::TrackingVolume(nullptr,
387 atlasBounds,
389 nullptr,
390 std::move(atlasVolumeArray),
391 "Atlas");
392
393 ATH_MSG_VERBOSE( "Atlas Tracking World volume built successfully." );
394
395
396 // glue the inner sector to be complete
397 m_trackingVolumeHelper->glueTrackingVolumes( *atlasInnerNegativeSector, Trk::positiveFaceXY,
398 innerNegativeFaceVolumes, Trk::negativeFaceXY );
399
400 m_trackingVolumeHelper->glueTrackingVolumes( *atlasInnerPositiveSector, Trk::negativeFaceXY,
401 innerPositiveFaceVolumes, Trk::positiveFaceXY );
402
403 ATH_MSG_VERBOSE( "Atlas Inner Sector glued successfully together." );
404
405 // iterators to the face volumes
406 auto volIter = innerCentralFaceVolumes.begin();
407 auto volIterEnd = innerCentralFaceVolumes.end();
408
409 // glue outer and inner sector together
410 std::vector<Trk::TrackingVolume*> atlasInnerOuterVolumes;
411 atlasInnerOuterVolumes.push_back(atlasInnerNegativeSector);
412 for ( ; volIter != volIterEnd; ++volIter)
413 if (*volIter) atlasInnerOuterVolumes.push_back(*volIter);
414 atlasInnerOuterVolumes.push_back(atlasInnerPositiveSector);
415
416 m_trackingVolumeHelper->glueTrackingVolumes(*atlasOuterSector, Trk::tubeInnerCover,
417 atlasInnerOuterVolumes, Trk::tubeOuterCover);
418
419 ATH_MSG_VERBOSE( "Atlas Inner/Outer Sector glued successfully together." );
420
421 // job done -> create the TrackingGeometry
422 atlasTrackingGeometry = std::make_unique<Trk::TrackingGeometry>(atlasVolume);
423
424 // detailed information about this tracking geometry
425 ATH_MSG_VERBOSE( "Atlas TrackingGeometry built with following parameters : ");
426 //ATH_MSG_VERBOSE( " - TrackingVolume containers : " << atlasTrackingGeometry->numberOfContainerVolumes() );
427 //ATH_MSG_VERBOSE( " - TrackingVolume at navigation level : " << atlasTrackingGeometry->numberOfContainerVolumes() );
428 //ATH_MSG_VERBOSE( " - Contained static layers : " << atlasTrackingGeometry->boundaryLayers().size());
429 ATH_MSG_VERBOSE( " - Unique material layers on boundaries : " << atlasTrackingGeometry->boundaryLayers().size());
430
431#ifdef TRKDETDESCR_MEMUSAGE
432 m_memoryLogger.refresh(getpid());
433 ATH_MSG_INFO( "[ memory usage ] After Outer Sector TrackingGeometry building: " );
434 ATH_MSG_INFO( m_memoryLogger );
435#endif
436
437 }
438
440 if (m_navigationLevel < 3)
441 atlasTrackingGeometry->registerNavigationLevel( Trk::NavigationLevel(m_navigationLevel.value()));
442 }
443 else ATH_MSG_WARNING( "atlasTrackingGeometry() ... atlasTrackingGeometry = 0, could not call registerNavigationLevel and propagateMagneticFieldProperties" );
444
445#ifdef TRKDETDESCR_MEMUSAGE
446 m_memoryLogger.refresh(getpid());
447 ATH_MSG_INFO( "[ memory usage ] End of TrackingGeometry building: " );
448 ATH_MSG_INFO( m_memoryLogger );
449#endif
450
451 // synchronize the layers
453 if (m_synchronizeLayers) atlasTrackingGeometry->synchronizeLayers(msg());
454
455 // compactify if configured to do so
456 if (m_compactify) atlasTrackingGeometry->compactify(msg());
457 }
459}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#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.
virtual std::unique_ptr< Trk::TrackingGeometry > trackingGeometry(const EventContext &ctx, Trk::TrackingVolume *tVol, SG::WriteCondHandle< TrackingGeometry > &whandle) const override
TrackingGeometry Interface method - optionally a pointer to Bounds Interface marked as not thread saf...
Gaudi::Property< bool > m_createWorld
ToolHandle< IGeometryBuilderCond > m_muonGeometryBuilderCond
ToolHandle< ITrackingVolumeHelper > m_trackingVolumeHelper
Material m_worldMaterial
the world material
Gaudi::Property< bool > m_synchronizeLayers
ToolHandle< IGeometryBuilderCond > m_caloGeometryBuilderCond
ToolHandle< IGeometryBuilderCond > m_inDetGeometryBuilderCond
Gaudi::Property< std::vector< double > > m_worldDimension
Gaudi::Property< std::vector< double > > m_worldMaterialProperties
Gaudi::Property< int > m_navigationLevel
ToolHandle< IGeometryBuilderCond > m_hgtdGeometryBuilderCond
std::unique_ptr< Trk::TrackingGeometry > atlasTrackingGeometry(const EventContext &ctx, SG::WriteCondHandle< TrackingGeometry > &whandle) const
TrackingGeometry for ATLAS setup.
Gaudi::Property< bool > m_compactify
ToolHandle< ITrackingVolumeArrayCreator > m_trackingVolumeArrayCreator
virtual StatusCode initialize() override
AlgTool initialize method.
virtual GeometrySignature geometrySignature() const override
The unique signature.
GeometryBuilderCond(const std::string &, const std::string &, const IInterface *)
Constructor.
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