ATLAS Offline Software
Loading...
Searching...
No Matches
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"
7
8#include "GeoModelKernel/GeoVDetectorManager.h"
9#include "GeoModelKernel/GeoShapeUnion.h"
10#include "GeoModelKernel/GeoShapeShift.h"
11#include "GeoModelKernel/GeoMaterial.h"
12#include "GeoModelKernel/GeoLogVol.h"
13#include "GeoModelKernel/GeoPhysVol.h"
14#include "GeoModelKernel/GeoTransform.h"
15
18
20
22
23#include "G4ReflectionFactory.hh"
24#include "G4LogicalBorderSurface.hh"
25#include "G4OpticalSurface.hh"
26#include "GeoModelKernel/throwExcept.h"
27
28#include <map>
29#include <iostream>
30#include <utility>
31
32Geo2G4Builder::Geo2G4Builder(const std::string& detectorName)
33 : AthMessaging("Geo2G4Builder")
34 , m_detectorName(detectorName)
35 , m_motherTransform(GeoTrf::Transform3D::Identity())
36{
37 if (m_pDetStore.retrieve().isFailure()) {
38 THROW_EXCEPTION("ERROR: Geo2G4Builder for detector "<< detectorName << " could not access the detector store.");
39 }
40
41 StatusCode sc = m_pDetStore->retrieve( m_theExpt, "ATLAS" );
42 if(sc.isFailure()){
43 THROW_EXCEPTION(detectorName<<" could not get GeoModelExperiment");
44 }
45 else {
46 const GeoVDetectorManager *theManager = m_theExpt->getManager(detectorName);
47 if (!theManager) {
48 THROW_EXCEPTION("Failed to retrieve manager "<<detectorName);
49 }
50 for(unsigned int i=0; i<theManager->getNumTreeTops(); ++i) {
51 m_treeTops.push_back(theManager->getTreeTop(i));
52 }
53
54 ATH_MSG_INFO("Found detector: top volume(s)");
55 for(unsigned int i=0; i<m_treeTops.size();++i) {
56 ATH_MSG_INFO( " Tree Top " << i << " " << m_treeTops[i]->getLogVol()->getName() );
57 }
58
59 if(m_treeTops.size()>1) {
60 // -------- -------- MATERIAL MANAGER -------- ----------
61 StoredMaterialManager* theMaterialManager = m_pDetStore->tryRetrieve<StoredMaterialManager>("MATERIALS");
62 if(theMaterialManager) {
63 m_matAir = theMaterialManager->getMaterial("std::Air");
64 }
65 else {
66 m_matAir = m_treeTops[0]->getLogVol()->getMaterial();
67 }
68 }
69
70 if (m_g2gSvc.retrieve().isFailure()) {
71 THROW_EXCEPTION("Failed to retrieve manager Geo2G4Svc");
72 }
73
74 m_theBuilder = m_g2gSvc->GetDefaultBuilder();
75 if(m_theBuilder)
76 ATH_MSG_INFO("Set volume builder ---> "<< m_theBuilder->GetKey());
77 else
78 ATH_MSG_WARNING("0 pointer to volume builder."
79 <<"\n Use 'DefaultBuilder' property of Geo2G4Svc or"
80 <<"\n 'GetVolumeBuilder' method of Geo2G4Builder");
81 }
82}
83
84G4LogicalVolume* Geo2G4Builder::BuildTree()
85{
86 ATH_MSG_DEBUG("Entering Geo2G4Builder::BuildTree()...");
87 G4LogicalVolume* result = nullptr;
88 OpticalVolumesMap* optical_volumes = nullptr;
89 const GeoBorderSurfaceContainer* surface_container = nullptr;
90
91 // Check whether we have to deal with optical surfaces
93 StatusCode sc = m_pDetStore->retrieve(surface_container,m_detectorName);
94 if(sc.isSuccess() && surface_container->size()>0) {
95 optical_volumes = new OpticalVolumesMap();
96 }
97 }
98
99 if(m_theBuilder) {
100 if(m_treeTops.size()==1) {
101 m_motherTransform = m_treeTops[0]->getX();
102 result = m_theBuilder->Build(m_treeTops[0],optical_volumes);
103 }
104 else {
105 // Create temporary GeoModel physical volume
106 // The shape is composed by TreeTop shapes + their transforms
107 const GeoShape& shFirst = (*(m_treeTops[0]->getLogVol()->getShape()))<<(m_treeTops[0]->getX());
108 const GeoShape* shResult = &shFirst;
109
110 for(unsigned int i=1; i<m_treeTops.size(); i++) {
111 shResult = & shResult->add((*(m_treeTops[i]->getLogVol()->getShape()))<<(m_treeTops[i]->getX()));
112 }
113
114 GeoLogVol* lvEnvelope = new GeoLogVol(m_detectorName,shResult,m_matAir);
115 GeoPhysVol* pvEnvelope = new GeoPhysVol(lvEnvelope);
116 m_theExpt->addTmpVolume(pvEnvelope);
117 result = m_theBuilder->Build(pvEnvelope);
118
119 // Get pointer to the World
120 PVConstLink world = m_treeTops[0]->getParent();
121
122 // Add all tree tops to the result
123 for(unsigned int i=0; i<m_treeTops.size(); i++) {
124 // Current Tree Top and its index
125 PVConstLink pv = m_treeTops[i];
126 std::optional<unsigned int> childIndx = world->indexOf(pv);
127
128 // Tree Top transformation
129 G4Transform3D theG4Position(Amg::EigenTransformToCLHEP(world->getXToChildVol(*childIndx)));
130
131 // Copy number
132 int id = 16969;
133 std::optional<int> Qint = world->getIdOfChildVol(*childIndx);
134 if(Qint) id = *Qint;
135
136 // PV Tree Top name
137 std::string nameTT = world->getNameOfChildVol(*childIndx);
138 if (nameTT == "ANON") nameTT = pv->getLogVol()->getName();
139
140
141 G4LogicalVolume* g4LV = m_theBuilder->Build(pv,optical_volumes);
142 G4ReflectionFactory::Instance()->Place(theG4Position,
143 nameTT,
144 g4LV,
145 result,
146 false,
147 id);
148 }
149 }
150 }
151
152 // build optical surfaces if necessary
153 if(optical_volumes) {
154 if(optical_volumes->size()>0) {
155 BuildOpticalSurfaces(surface_container,optical_volumes);
156 }
157 else {
158 ATH_MSG_WARNING("Optical volumes apparently requested, but none found! Deleting temps");
159 }
160 delete optical_volumes;
161 }
162
163 return result;
164}
165
166
168{
169 m_theBuilder = m_g2gSvc->GetVolumeBuilder(std::move(bname));
170 return m_theBuilder;
171}
172
174 const OpticalVolumesMap* optical_volumes)
175{
176 Geo2G4OpticalSurfaceFactory surfaceFactory;
177
178 for (const GeoBorderSurface& border_surface : *surface_container)
179 {
180 // Build Optical Surface
181 G4OpticalSurface* g4OptSurface = surfaceFactory.Build(border_surface.getOptSurface());
182
183 G4VPhysicalVolume* g4PV1 = 0;
184 G4VPhysicalVolume* g4PV2 = 0;
185 OpticalVolumesMap::const_iterator volIt;
186
187 // First physical volume
188 volIt = optical_volumes->find(border_surface.getPV1());
189 if(volIt == optical_volumes->end())
190 {
191 ATH_MSG_WARNING("Unable to find " << border_surface.getPV1()->getLogVol()->getName() << " in Optical Volumes map");
192 continue;
193 }
194 g4PV1 = volIt.operator->()->second;
195
196 // Second physical volume
197 volIt = optical_volumes->find(border_surface.getPV2());
198 if(volIt == optical_volumes->end())
199 {
200 ATH_MSG_WARNING("Unable to find " << border_surface.getPV2()->getLogVol()->getName() << " in Optical Volumes map");
201 continue;
202 }
203 g4PV2 = volIt.operator->()->second;
204
205 // G4LogicalBorderSurface
206 G4LogicalBorderSurface* g4BorderSurface __attribute__((unused)) = new G4LogicalBorderSurface(border_surface.getName(),g4PV1,g4PV2,g4OptSurface);
207 }
208}
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Eigen::Affine3d Transform3D
std::vector< GeoBorderSurface > GeoBorderSurfaceContainer
static Double_t sc
std::map< const GeoOpticalPhysVol *, G4VPhysicalVolume *, std::less< const GeoOpticalPhysVol * > > OpticalVolumesMap
__attribute__((always_inline)) inline uint16_t TileCalibDrawerBase
void unused(Args &&...)
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
GeoModelExperiment * m_theExpt
std::vector< PVConstLink > m_treeTops
VolumeBuilder * GetVolumeBuilder(std::string)
const GeoMaterial * m_matAir
Geo2G4Builder(const std::string &detectorName)
void BuildOpticalSurfaces(const GeoBorderSurfaceContainer *surface_container, const OpticalVolumesMap *optical_volumes)
G4LogicalVolume * BuildTree()
std::string m_detectorName
ServiceHandle< IGeo2G4Svc > m_g2gSvc
ServiceHandle< StoreGateSvc > m_pDetStore
VolumeBuilder * m_theBuilder
GeoTrf::Transform3D m_motherTransform
G4OpticalSurface * Build(const GeoOpticalSurface *)
This class holds one or more material managers and makes them storeable, under StoreGate.
virtual const GeoMaterial * getMaterial(const std::string &name)=0
HepGeom::Transform3D EigenTransformToCLHEP(const Amg::Transform3D &eigenTransf)
Converts an Eigen-based Amg::Transform3D into a CLHEP-based HepGeom::Transform3D.
#define THROW_EXCEPTION(MESSAGE)
Definition throwExcept.h:10