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 if (m_pDetStore.retrieve().isFailure()) {
37 THROW_EXCEPTION("ERROR: Geo2G4Builder for detector "<< detectorName << " could not access the detector store.");
38 }
39
40 StatusCode sc = m_pDetStore->retrieve( m_theExpt, "ATLAS" );
41 if(sc.isFailure()){
42 THROW_EXCEPTION(detectorName<<" could not get GeoModelExperiment");
43 }
44
45 const GeoVDetectorManager *theManager = m_theExpt->getManager(detectorName);
46 if (!theManager) {
47 THROW_EXCEPTION("Failed to retrieve manager "<<detectorName);
48 }
49 ATH_MSG_DEBUG("Recieve detctor manager "<<detectorName);
50 for(unsigned int i=0; i<theManager->getNumTreeTops(); ++i) {
51 m_treeTops.push_back(theManager->getTreeTop(i));
52 }
53
54 ATH_MSG_DEBUG("Found detector: top volume(s)");
55 for(unsigned int i=0; i<m_treeTops.size();++i) {
56 ATH_MSG_DEBUG( " 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 } else {
65 m_matAir = m_treeTops[0]->getLogVol()->getMaterial();
66 }
67 }
68
69 if (m_g2gSvc.retrieve().isFailure()) {
70 THROW_EXCEPTION("Failed to retrieve manager Geo2G4Svc");
71 }
72
73 m_theBuilder = m_g2gSvc->GetDefaultBuilder();
74 if(m_theBuilder) {
75 ATH_MSG_INFO("Set volume builder ---> "<< m_theBuilder->GetKey());
76 } else {
77 ATH_MSG_WARNING("0 pointer to volume builder."
78 <<"\n Use 'DefaultBuilder' property of Geo2G4Svc or"
79 <<"\n 'GetVolumeBuilder' method of Geo2G4Builder");
80 }
81}
82
83G4LogicalVolume* Geo2G4Builder::BuildTree()
84{
85 ATH_MSG_DEBUG("Entering Geo2G4Builder::BuildTree()...");
86 G4LogicalVolume* result = nullptr;
87 std::unique_ptr<OpticalVolumesMap> optical_volumes{};
88 const GeoBorderSurfaceContainer* surface_container = nullptr;
89
90 // Check whether we have to deal with optical surfaces
92 StatusCode sc = m_pDetStore->retrieve(surface_container,m_detectorName);
93 if(sc.isSuccess() && surface_container->size()>0) {
94 optical_volumes = std::make_unique<OpticalVolumesMap>();
95 }
96 }
97
98 if(m_theBuilder) {
99 if(m_treeTops.size()==1) {
100 m_motherTransform = m_treeTops[0]->getX();
101 result = m_theBuilder->Build(m_treeTops[0], optical_volumes.get());
102 } else if (!m_treeTops.empty()) {
103 // Create temporary GeoModel physical volume
104 // The shape is composed by TreeTop shapes + their transforms
105 const GeoShape& shFirst = (*(m_treeTops[0]->getLogVol()->getShape()))<<(m_treeTops[0]->getX());
106 GeoIntrusivePtr<const GeoShape> shResult{&shFirst};
107
108 for(unsigned int i=1; i<m_treeTops.size(); i++) {
109 GeoIntrusivePtr<const GeoShape> booleanOp{&shResult->add((*(m_treeTops[i]->getLogVol()->getShape()))<<(m_treeTops[i]->getX()))};
110 shResult = booleanOp;
111 }
112
113 auto lvEnvelope = make_intrusive<GeoLogVol>(m_detectorName, shResult, m_matAir);
114 auto pvEnvelope = make_intrusive<GeoPhysVol>(lvEnvelope);
115 m_theExpt->addTmpVolume(pvEnvelope);
116 result = m_theBuilder->Build(pvEnvelope);
117
118 // Get pointer to the World
119 PVConstLink world = m_treeTops[0]->getParent();
120
121 // Add all tree tops to the result
122 for(unsigned int i=0; i<m_treeTops.size(); i++) {
123 // Current Tree Top and its index
124 PVConstLink pv = m_treeTops[i];
125 std::optional<unsigned int> childIndx = world->indexOf(pv);
126
127 // Tree Top transformation
128 G4Transform3D theG4Position(Amg::EigenTransformToCLHEP(world->getXToChildVol(*childIndx)));
129
130 // Copy number
131 int id = 16969;
132 std::optional<int> Qint = world->getIdOfChildVol(*childIndx);
133 if(Qint) id = *Qint;
134
135 // PV Tree Top name
136 std::string nameTT = world->getNameOfChildVol(*childIndx);
137 if (nameTT == "ANON") nameTT = pv->getLogVol()->getName();
138
139
140 G4LogicalVolume* g4LV = m_theBuilder->Build(pv, optical_volumes.get());
141 G4ReflectionFactory::Instance()->Place(theG4Position,
142 nameTT,
143 g4LV,
144 result,
145 false,
146 id);
147 }
148 }
149 }
150
151 // build optical surfaces if necessary
152 if(optical_volumes) {
153 if(optical_volumes->size()>0) {
154 BuildOpticalSurfaces(surface_container,optical_volumes.get());
155 } else {
156 ATH_MSG_WARNING("Optical volumes apparently requested, but none found! Deleting temps");
157 }
158 }
159
160 return result;
161}
162
163
165{
166 m_theBuilder = m_g2gSvc->GetVolumeBuilder(std::move(bname));
167 return m_theBuilder;
168}
169
171 const OpticalVolumesMap* optical_volumes)
172{
173 Geo2G4OpticalSurfaceFactory surfaceFactory;
174
175 for (const GeoBorderSurface& border_surface : *surface_container)
176 {
177 // Build Optical Surface
178 G4OpticalSurface* g4OptSurface = surfaceFactory.Build(border_surface.getOptSurface());
179
180 G4VPhysicalVolume* g4PV1 = 0;
181 G4VPhysicalVolume* g4PV2 = 0;
182 OpticalVolumesMap::const_iterator volIt;
183
184 // First physical volume
185 volIt = optical_volumes->find(border_surface.getPV1());
186 if(volIt == optical_volumes->end())
187 {
188 ATH_MSG_WARNING("Unable to find " << border_surface.getPV1()->getLogVol()->getName() << " in Optical Volumes map");
189 continue;
190 }
191 g4PV1 = volIt.operator->()->second;
192
193 // Second physical volume
194 volIt = optical_volumes->find(border_surface.getPV2());
195 if(volIt == optical_volumes->end())
196 {
197 ATH_MSG_WARNING("Unable to find " << border_surface.getPV2()->getLogVol()->getName() << " in Optical Volumes map");
198 continue;
199 }
200 g4PV2 = volIt.operator->()->second;
201
202 // G4LogicalBorderSurface
203 G4LogicalBorderSurface* g4BorderSurface __attribute__((unused)) = new G4LogicalBorderSurface(border_surface.getName(),g4PV1,g4PV2,g4OptSurface);
204 }
205}
#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
if(febId1==febId2)
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