ATLAS Offline Software
Geo2G4Builder.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "Geo2G4Builder.h"
6 #include "Geo2G4SvcAccessor.h"
9 
10 #include "GeoModelKernel/GeoVDetectorManager.h"
11 #include "GeoModelKernel/GeoShapeUnion.h"
12 #include "GeoModelKernel/GeoShapeShift.h"
13 #include "GeoModelKernel/GeoMaterial.h"
14 #include "GeoModelKernel/GeoLogVol.h"
15 #include "GeoModelKernel/GeoPhysVol.h"
16 #include "GeoModelKernel/GeoTransform.h"
17 
20 
22 
23 #include "GaudiKernel/ISvcLocator.h"
24 #include "GaudiKernel/Bootstrap.h"
25 #include "StoreGate/StoreGateSvc.h"
26 
27 #include "G4ReflectionFactory.hh"
28 #include "G4LogicalBorderSurface.hh"
29 #include "G4OpticalSurface.hh"
30 #include "GeoModelHelpers/throwExcept.h"
31 
32 #include <map>
33 #include <iostream>
34 #include <utility>
35 
36 Geo2G4Builder::Geo2G4Builder(const std::string& detectorName)
37  : AthMessaging("Geo2G4Builder")
38  , m_detectorName(detectorName)
39  , m_motherTransform(GeoTrf::Transform3D::Identity())
40 {
41  ISvcLocator* svcLocator = Gaudi::svcLocator(); // from Bootstrap
42  StatusCode sc=svcLocator->service("DetectorStore",m_pDetStore);
43  if (sc.isFailure()) {
44  THROW_EXCEPTION("ERROR: Geo2G4Builder for detector "<< detectorName << " could not access the detector store.");
45  }
46 
47  sc = m_pDetStore->retrieve( m_theExpt, "ATLAS" );
48  if(sc.isFailure()){
49  THROW_EXCEPTION(detectorName<<" could not get GeoModelExperiment");
50  }
51  else {
52  const GeoVDetectorManager *theManager = m_theExpt->getManager(detectorName);
53  if (!theManager) {
54  THROW_EXCEPTION("Failed to retrieve manager "<<detectorName);
55  }
56  for(unsigned int i=0; i<theManager->getNumTreeTops(); ++i) {
57  m_treeTops.push_back(theManager->getTreeTop(i));
58  }
59 
60  ATH_MSG_INFO("Found detector: top volume(s)");
61  for(unsigned int i=0; i<m_treeTops.size();++i) {
62  ATH_MSG_INFO( " Tree Top " << i << " " << m_treeTops[i]->getLogVol()->getName() );
63  }
64 
65  if(m_treeTops.size()>1) {
66  // -------- -------- MATERIAL MANAGER -------- ----------
67  StoredMaterialManager* theMaterialManager = m_pDetStore->tryRetrieve<StoredMaterialManager>("MATERIALS");
68  if(theMaterialManager) {
69  m_matAir = theMaterialManager->getMaterial("std::Air");
70  }
71  else {
72  m_matAir = m_treeTops[0]->getLogVol()->getMaterial();
73  }
74  }
75 
77  Geo2G4SvcBase *g=accessor.GetGeo2G4Svc();
78  m_theBuilder=g->GetDefaultBuilder();
79  if(m_theBuilder)
80  ATH_MSG_INFO("Set volume builder ---> "<< m_theBuilder->GetKey());
81  else
82  ATH_MSG_WARNING("0 pointer to volume builder."
83  <<"\n Use 'DefaultBuilder' property of Geo2G4Svc or"
84  <<"\n 'GetVolumeBuilder' method of Geo2G4Builder");
85  }
86 }
87 
88 G4LogicalVolume* Geo2G4Builder::BuildTree()
89 {
90  ATH_MSG_DEBUG("Entering Geo2G4Builder::BuildTree()...");
91  G4LogicalVolume* result = nullptr;
92  OpticalVolumesMap* optical_volumes = nullptr;
93  const GeoBorderSurfaceContainer* surface_container = nullptr;
94 
95  // Check whether we have to deal with optical surfaces
97  StatusCode sc = m_pDetStore->retrieve(surface_container,m_detectorName);
98  if(sc.isSuccess() && surface_container->size()>0) {
99  optical_volumes = new OpticalVolumesMap();
100  }
101  }
102 
103  if(m_theBuilder) {
104  if(m_treeTops.size()==1) {
105  m_motherTransform = m_treeTops[0]->getX();
106  result = m_theBuilder->Build(m_treeTops[0],optical_volumes);
107  }
108  else {
109  // Create temporary GeoModel physical volume
110  // The shape is composed by TreeTop shapes + their transforms
111  const GeoShape& shFirst = (*(m_treeTops[0]->getLogVol()->getShape()))<<(m_treeTops[0]->getX());
112  const GeoShape* shResult = &shFirst;
113 
114  for(unsigned int i=1; i<m_treeTops.size(); i++) {
115  shResult = & shResult->add((*(m_treeTops[i]->getLogVol()->getShape()))<<(m_treeTops[i]->getX()));
116  }
117 
118  GeoLogVol* lvEnvelope = new GeoLogVol(m_detectorName,shResult,m_matAir);
119  GeoPhysVol* pvEnvelope = new GeoPhysVol(lvEnvelope);
120  m_theExpt->addTmpVolume(pvEnvelope);
121  result = m_theBuilder->Build(pvEnvelope);
122 
123  // Get pointer to the World
124  PVConstLink world = m_treeTops[0]->getParent();
125 
126  // Add all tree tops to the result
127  for(unsigned int i=0; i<m_treeTops.size(); i++) {
128  // Current Tree Top and its index
129  PVConstLink pv = m_treeTops[i];
130  Query<unsigned int> childIndx = world->indexOf(pv);
131 
132  // Tree Top transformation
133  G4Transform3D theG4Position(Amg::EigenTransformToCLHEP(world->getXToChildVol(childIndx)));
134 
135  // Copy number
136  int id = 16969;
137  Query<int> Qint = world->getIdOfChildVol(childIndx);
138  if(Qint.isValid()) id = Qint;
139 
140  // PV Tree Top name
141  std::string nameTT = world->getNameOfChildVol(childIndx);
142  if (nameTT == "ANON") nameTT = pv->getLogVol()->getName();
143 
144 
145  G4LogicalVolume* g4LV = m_theBuilder->Build(pv,optical_volumes);
146  G4ReflectionFactory::Instance()->Place(theG4Position,
147  nameTT,
148  g4LV,
149  result,
150  false,
151  id);
152  }
153  }
154  }
155 
156  // build optical surfaces if necessary
157  if(optical_volumes) {
158  if(optical_volumes->size()>0) {
159  BuildOpticalSurfaces(surface_container,optical_volumes);
160  }
161  else {
162  ATH_MSG_WARNING("Optical volumes apparently requested, but none found! Deleting temps");
163  }
164  delete optical_volumes;
165  }
166 
167  return result;
168 }
169 
170 
172 {
174  Geo2G4SvcBase *g=accessor.GetGeo2G4Svc();
175 
176  m_theBuilder=g->GetVolumeBuilder(std::move(bname));
177  return m_theBuilder;
178 }
179 
181  const OpticalVolumesMap* optical_volumes)
182 {
183  Geo2G4OpticalSurfaceFactory surfaceFactory;
184 
185  for (const GeoBorderSurface& border_surface : *surface_container)
186  {
187  // Build Optical Surface
188  G4OpticalSurface* g4OptSurface = surfaceFactory.Build(border_surface.getOptSurface());
189 
190  G4VPhysicalVolume* g4PV1 = 0;
191  G4VPhysicalVolume* g4PV2 = 0;
192  OpticalVolumesMap::const_iterator volIt;
193 
194  // First physical volume
195  volIt = optical_volumes->find(border_surface.getPV1());
196  if(volIt == optical_volumes->end())
197  {
198  ATH_MSG_WARNING("Unable to find " << border_surface.getPV1()->getLogVol()->getName() << " in Optical Volumes map");
199  continue;
200  }
201  g4PV1 = volIt.operator->()->second;
202 
203  // Second physical volume
204  volIt = optical_volumes->find(border_surface.getPV2());
205  if(volIt == optical_volumes->end())
206  {
207  ATH_MSG_WARNING("Unable to find " << border_surface.getPV2()->getLogVol()->getName() << " in Optical Volumes map");
208  continue;
209  }
210  g4PV2 = volIt.operator->()->second;
211 
212  // G4LogicalBorderSurface
213  G4LogicalBorderSurface* g4BorderSurface __attribute__((unused)) = new G4LogicalBorderSurface(border_surface.getName(),g4PV1,g4PV2,g4OptSurface);
214  }
215 }
Geo2G4Builder::m_treeTops
std::vector< PVConstLink > m_treeTops
Definition: Geo2G4Builder.h:55
Geo2G4Builder::m_matAir
const GeoMaterial * m_matAir
Definition: Geo2G4Builder.h:59
StoreGateSvc::contains
bool contains(const TKEY &key) const
Look up a keyed object in TDS (compare also tryRetrieve) returns false if object not available in TDS...
get_generator_info.result
result
Definition: get_generator_info.py:21
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
VolumeBuilder::Build
virtual G4LogicalVolume * Build(PVConstLink pv, OpticalVolumesMap *optical_volumes=0)=0
AthMsgStreamMacros.h
StoreGateSvc::tryRetrieve
T * tryRetrieve() const
Variant of the above which doesn't print a warning message.
VolumeBuilder
Definition: Simulation/G4Utilities/Geo2G4/src/VolumeBuilder.h:22
OpticalVolumesMap
std::map< const GeoOpticalPhysVol *, G4VPhysicalVolume *, std::less< const GeoOpticalPhysVol * > > OpticalVolumesMap
Definition: Simulation/G4Utilities/Geo2G4/src/VolumeBuilder.h:19
THROW_EXCEPTION
#define THROW_EXCEPTION(MSG)
Definition: MMReadoutElement.cxx:48
Geo2G4Builder::BuildOpticalSurfaces
void BuildOpticalSurfaces(const GeoBorderSurfaceContainer *surface_container, const OpticalVolumesMap *optical_volumes)
Definition: Geo2G4Builder.cxx:180
Geo2G4Builder::m_motherTransform
GeoTrf::Transform3D m_motherTransform
Definition: Geo2G4Builder.h:54
GeoModelExperiment::addTmpVolume
void addTmpVolume(PVConstLink volume)
Definition: GeoModelExperiment.cxx:84
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
StoreGateSvc::retrieve
StatusCode retrieve(const T *&ptr) const
Retrieve the default object into a const T*.
GeoModelExperiment.h
lumiFormat.i
int i
Definition: lumiFormat.py:92
GeoBorderSurface
Definition: GeoBorderSurface.h:18
python.CaloCondTools.g
g
Definition: CaloCondTools.py:15
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
VolumeBuilder::GetKey
std::string GetKey() const
Definition: Simulation/G4Utilities/Geo2G4/src/VolumeBuilder.h:30
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
Geo2G4Builder::BuildTree
G4LogicalVolume * BuildTree()
Definition: Geo2G4Builder.cxx:88
Geo2G4Builder::m_pDetStore
StoreGateSvc * m_pDetStore
Definition: Geo2G4Builder.h:60
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
GeoModelExperiment::getManager
const GeoVDetectorManager * getManager(const std::string &name) const
Definition: GeoModelExperiment.cxx:52
Geo2G4OpticalSurfaceFactory
Definition: Geo2G4OpticalSurfaceFactory.h:16
Geo2G4Builder.h
StoredMaterialManager.h
xAOD::JetAttributeAccessor::accessor
const AccessorWrapper< T > * accessor(xAOD::JetAttribute::AttributeID id)
Returns an attribute accessor corresponding to an AttributeID.
Definition: JetAccessorMap.h:26
unused
void unused(Args &&...)
Definition: VP1ExpertSettings.cxx:39
__attribute__
__attribute__((always_inline)) inline uint16_t TileCalibDrawerBase
Definition: TileCalibDrawerBase.h:190
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
GeoBorderSurfaceContainer
std::vector< GeoBorderSurface > GeoBorderSurfaceContainer
Definition: GeoBorderSurfaceContainer.h:12
Geo2G4SvcAccessor
Definition: Geo2G4SvcAccessor.h:14
Amg::EigenTransformToCLHEP
HepGeom::Transform3D EigenTransformToCLHEP(const Amg::Transform3D &eigenTransf)
Converts an Eigen-based Amg::Transform3D into a CLHEP-based HepGeom::Transform3D.
Definition: CLHEPtoEigenConverter.h:120
python.changerun.pv
pv
Definition: changerun.py:81
StoredMaterialManager::getMaterial
virtual const GeoMaterial * getMaterial(const std::string &name)=0
StoredMaterialManager
This class holds one or more material managers and makes them storeable, under StoreGate.
Definition: StoredMaterialManager.h:28
Geo2G4SvcBase
Definition: Geo2G4SvcBase.h:14
Geo2G4Builder::Geo2G4Builder
Geo2G4Builder(const std::string &detectorName)
Definition: Geo2G4Builder.cxx:36
Geo2G4Builder::GetVolumeBuilder
VolumeBuilder * GetVolumeBuilder(std::string)
Definition: Geo2G4Builder.cxx:171
Geo2G4OpticalSurfaceFactory.h
StoreGateSvc.h
Geo2G4Builder::m_theExpt
GeoModelExperiment * m_theExpt
Definition: Geo2G4Builder.h:61
Geo2G4SvcBase.h
Geo2G4SvcAccessor.h
Geo2G4Builder::m_theBuilder
VolumeBuilder * m_theBuilder
Definition: Geo2G4Builder.h:56
Geo2G4OpticalSurfaceFactory::Build
G4OpticalSurface * Build(const GeoOpticalSurface *)
Definition: Geo2G4OpticalSurfaceFactory.cxx:16
Geo2G4Builder::m_detectorName
std::string m_detectorName
Definition: Geo2G4Builder.h:53