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