ATLAS Offline Software
ExtParameterisedVolumeBuilder.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 #include "Geo2G4AssemblyVolume.h"
7 #include "Geo2G4LVFactory.h"
9 #include "G4LogicalVolume.hh"
10 
11 #include "G4PVPlacement.hh"
12 #include "G4ReflectionFactory.hh"
13 #include "G4VPVParameterisation.hh"
14 #include "G4PVParameterised.hh"
15 #include "globals.hh"
16 
18 
19 #include "GeoModelKernel/GeoAccessVolAndSTAction.h"
20 #include "GeoModelKernel/GeoVolumeCursor.h"
21 #include "GeoModelKernel/GeoMaterial.h"
22 #include "GeoModelKernel/GeoLogVol.h"
23 #include "GeoModelKernel/GeoSerialTransformer.h"
25 
26 #include "StoreGate/StoreGateSvc.h"
27 #include <iostream>
28 
30 
33  AthMessaging(n),
34  m_getMatEther(true),
35  m_matEther(nullptr),
36  m_matHypUr(nullptr),
37  m_G4AssemblyFactory(G4AssemblyFactory)
38 {
39 }
40 
41 G4LogicalVolume* ExtParameterisedVolumeBuilder::Build(const PVConstLink theGeoPhysVolume, OpticalVolumesMap* optical_volumes)
42 {
43  PVConstLink theGeoPhysChild;
44  const GeoSerialTransformer* serialTransformerChild{nullptr};
45  G4LogicalVolume* theG4LogChild{nullptr};
46  unsigned int numChildNodes; // number of child nodes (PV and ST)
47  bool descend; // flag to continue geo tree navigation
48  bool serialExists = false; // flag for existence of ST among childs
49  std::string nameChild;
50 
52 
53  static Geo2G4LVFactory LVFactory;
54 
55  G4LogicalVolume* theG4LogVolume = LVFactory.Build(theGeoPhysVolume,descend);
56 
57  if(!descend) return theG4LogVolume;
58 
59  numChildNodes = theGeoPhysVolume->getNChildVolAndST();
60 
61  // *****************************************************************
62  // **
63  // ** If m_ST2Param flag is set:
64  // ** Check if there's any serial transformer among child volumes
65  // **
66  // *****************************************************************
67 
68  if(m_paramOn)
69  for(size_t counter1=0; counter1<numChildNodes; counter1++)
70  {
71  GeoAccessVolAndSTAction actionVolAndST(counter1);
72  theGeoPhysVolume->exec(&actionVolAndST);
73 
74  if((serialTransformerChild=actionVolAndST.getSerialTransformer()))
75  {
76  nameChild = actionVolAndST.getName();
77  serialExists = true;
78  break;
79  }
80  }
81  // ***************************************************************************
82  // ** Next steps:
83  // **
84  // ** 1. If ST exists and numChildNodes==1, translate ST to G4 ST
85  // **
86  // ** 2. If ST exists and numChildNodes !=1, print information message and
87  // ** translate ST to single placements as well as all other child volumes
88  // **
89  // ** 3. There's no ST - ok, nothing special ...
90  // **
91  // ***************************************************************************
92 
93  if(serialExists && (numChildNodes==1))
94  {
95  theGeoPhysChild = serialTransformerChild->getVolume();
96 
97  // Build the child
98  if(!(theG4LogChild = Build(theGeoPhysChild,optical_volumes))) return nullptr;
99 
100  if (nameChild == "ANON") nameChild=theG4LogChild->GetName();
101  nameChild += "_Param";
102 
103  Geo2G4STParameterisation* stParameterisation = new Geo2G4STParameterisation(serialTransformerChild->getFunction(),
104  serialTransformerChild->getNCopies());
105 
106  [[maybe_unused]] G4VPhysicalVolume* pvParametrised = new G4PVParameterised(nameChild,
107  theG4LogChild,
108  theG4LogVolume,
109  kUndefined,
110  serialTransformerChild->getNCopies(),
111  stParameterisation);
112  }
113  else
114  {
115  if(serialExists)
116  {
117  std::string volName = theGeoPhysVolume->getLogVol()->getName();
118  PrintSTInfo(volName);
119  }
120 
121  GeoVolumeCursor av(theGeoPhysVolume);
122  while (!av.atEnd())
123  {
124  int id = 16969;
125 
126  // Get child phys volume
127  theGeoPhysChild = av.getVolume();
128  // Get its transform
129  G4Transform3D theG4Position(Amg::EigenTransformToCLHEP(av.getTransform()));
130 
131  Query<int> Qint = av.getId();
132  if(Qint.isValid()) id = Qint;
133 
134  bool isEther = theGeoPhysChild->getLogVol()->getMaterial()->getName().compare("special::Ether")==0;
135  bool isHypUr = theGeoPhysChild->getLogVol()->getMaterial()->getName().compare("special::HyperUranium")==0;
136 
137  if(isEther) {
138  Geo2G4AssemblyVolume* assembly = BuildAssembly(theGeoPhysChild);
139 
140  if(Qint.isValid()) {
141  assembly->MakeImprint(theG4LogVolume,theG4Position,id);
142  }
143  else {
144  assembly->MakeImprint(theG4LogVolume,theG4Position);
145  }
146  }
147  else if(isHypUr) {
148  Geo2G4AssemblyVolume* assembly = BuildAssembly(theGeoPhysChild);
149 
150  if(Qint.isValid()) {
151  assembly->MakeImprint(theG4LogVolume,theG4Position,id,true);
152  }
153  else {
154  assembly->MakeImprint(theG4LogVolume,theG4Position,0,true);
155  }
156  }
157  else {
158  nameChild = av.getName();
159 
160  // Build the child
161  if(!(theG4LogChild = Build(theGeoPhysChild,optical_volumes))) return nullptr;
162 
163  if (nameChild == "ANON") nameChild=theG4LogChild->GetName();
164 
165  G4PhysicalVolumesPair pvPair = G4ReflectionFactory::Instance()->Place(theG4Position
166  , nameChild
167  , theG4LogChild
168  , theG4LogVolume
169  , false
170  , id);
171 
172  // if GeoModel volume is optical store it in the map
173  if(optical_volumes!=0) {
174  const GeoOpticalPhysVol* opticalGeoPhysChild =
175  dynamic_cast < const GeoOpticalPhysVol* >(theGeoPhysChild.operator->());
176  if(opticalGeoPhysChild)
177  (*optical_volumes)[opticalGeoPhysChild] = pvPair.first;
178  }
179  }
180 
181  av.next();
182  }
183  }
184 
185  return theG4LogVolume;
186 }
187 
189 {
190  PVConstLink theGeoPhysChild;
191  G4LogicalVolume* theG4LogChild{nullptr};
192  Geo2G4AssemblyVolume* theG4AssemblyChild{nullptr};
193  bool descend; // flag to continue geo tree navigation
194 
196 
198 
199  if(!descend) return assemblyVolume;
200 
201  // Loop over child volumes and add them to the Geo2G4AssemblyVolume
202  GeoVolumeCursor av(pv);
203  while (!av.atEnd())
204  {
205  theGeoPhysChild = av.getVolume();
206  std::string nameChild = av.getName();
207 
208  std::string strVolume = std::string("Volume ") + nameChild + " ("
209  + theGeoPhysChild->getLogVol()->getName() + ")";
210 
211  // Check if it is an assembly
212  bool isEther = theGeoPhysChild->getLogVol()->getMaterial()->getName().compare("special::Ether")==0;
213  bool isHypUr = theGeoPhysChild->getLogVol()->getMaterial()->getName().compare("special::HyperUranium")==0;
214 
215  if(isEther || isHypUr) {
216  // Build the child assembly
217  if(!(theG4AssemblyChild = BuildAssembly(theGeoPhysChild))) return nullptr;
218 
219  // Get its transform
220  G4Transform3D theG4Position(Amg::EigenTransformToCLHEP(av.getTransform()));
221 
222  assemblyVolume->AddPlacedAssembly(theG4AssemblyChild,theG4Position);
223  }
224  else {
225  Query<int> Qint = av.getId();
226 
227  // Build the child
228  if(!(theG4LogChild = Build(theGeoPhysChild))) return nullptr;
229 
230  // Get its transform
231  G4Transform3D theG4Position(Amg::EigenTransformToCLHEP(av.getTransform()));
232 
233  int placedID = 0;
234  if(Qint.isValid()) placedID = Qint;
235 
236  std::string placedName = nameChild=="ANON" ? "" : nameChild;
237 
238  assemblyVolume->AddPlacedVolume(theG4LogChild,theG4Position,placedID,placedName);
239  }
240 
241  av.next();
242  }
243 
244  return assemblyVolume;
245 }
246 
247 void ExtParameterisedVolumeBuilder::PrintSTInfo(const std::string& volume) const
248 {
249  ATH_MSG_INFO ( "**********************************************" );
250  ATH_MSG_INFO ( "** " );
251  ATH_MSG_INFO ( "** The Volume " << volume );
252  ATH_MSG_INFO ( "** Has children of two different types" );
253  ATH_MSG_INFO ( "** PeoPhysVolume and GeoSerialTransformer" );
254  ATH_MSG_INFO ( "** In this case GeoSerialTransformer will be " );
255  ATH_MSG_INFO ( "** translated into G4 placement but not in " );
256  ATH_MSG_INFO ( "** G4Parameterisation" );
257  ATH_MSG_INFO ( "** " );
258  ATH_MSG_INFO ( "********************************************** " );
259 }
260 
262 {
263  StoreGateSvc* pDetStore{nullptr};
264  ISvcLocator* svcLocator = Gaudi::svcLocator();
265  if(svcLocator->service("DetectorStore",pDetStore).isFailure()) {
266  ATH_MSG_ERROR ( "ExtParameterisedVolumeBuilder: Unable to access Detector Store" );
267  }
268  else {
269  StoredMaterialManager* theMaterialManager = pDetStore->tryRetrieve<StoredMaterialManager>("MATERIALS");
270  if(theMaterialManager) {
271  m_matEther = theMaterialManager->getMaterial("special::Ether");
272  m_matHypUr = theMaterialManager->getMaterial("special::HyperUranium");
273  }
274  }
275  m_getMatEther = false;
276 }
Geo2G4STParameterisation
Definition: Geo2G4STParameterisation.h:32
GeoOpticalPhysVol
Ensure that the extensions for the Vector3D are properly loaded.
Definition: GeoOpticalPhysVol.h:14
Geo2G4AssemblyVolume.h
ExtParameterisedVolumeBuilder::m_getMatEther
bool m_getMatEther
Definition: ExtParameterisedVolumeBuilder.h:33
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
ExtParameterisedVolumeBuilder::m_G4AssemblyFactory
Geo2G4AssemblyFactory * m_G4AssemblyFactory
Definition: ExtParameterisedVolumeBuilder.h:37
ExtParameterisedVolumeBuilder::Build
virtual G4LogicalVolume * Build(PVConstLink pv, OpticalVolumesMap *optical_volumes=0) override
Definition: ExtParameterisedVolumeBuilder.cxx:41
ExtParameterisedVolumeBuilder::m_matHypUr
const GeoMaterial * m_matHypUr
Definition: ExtParameterisedVolumeBuilder.h:35
VolumeBuilder
Definition: Simulation/G4Utilities/Geo2G4/src/VolumeBuilder.h:22
ExtParameterisedVolumeBuilder::PrintSTInfo
void PrintSTInfo(const std::string &volume) const
Prints info when some PhysVol contains both types (PV and ST) of daughters.
Definition: ExtParameterisedVolumeBuilder.cxx:247
ServiceAccessor.h
Geo2G4AssemblyVolume::MakeImprint
void MakeImprint(G4LogicalVolume *pMotherLV, G4ThreeVector &translationInMother, const G4RotationMatrix *pRotationInMother, G4int copyNumBase=0, G4bool ITkScheme=false, G4bool surfCheck=false)
Definition: Geo2G4AssemblyVolume.cxx:289
OpticalVolumesMap
std::map< const GeoOpticalPhysVol *, G4VPhysicalVolume *, std::less< const GeoOpticalPhysVol * > > OpticalVolumesMap
Definition: Simulation/G4Utilities/Geo2G4/src/VolumeBuilder.h:19
descend
void descend(TDirectory *d, int level, int maxdepth, const std::vector< std::string > &labels)
Definition: chains.cxx:107
ExtParameterisedVolumeBuilder::BuildAssembly
Geo2G4AssemblyVolume * BuildAssembly(const PVConstLink &pv)
Definition: ExtParameterisedVolumeBuilder.cxx:188
Geo2G4AssemblyFactory::Build
Geo2G4AssemblyVolume * Build(const PVConstLink &thePhys, bool &descend)
Definition: Geo2G4AssemblyFactory.cxx:17
ExtParameterisedVolumeBuilder::m_matEther
const GeoMaterial * m_matEther
Definition: ExtParameterisedVolumeBuilder.h:34
StoreGateSvc
The Athena Transient Store API.
Definition: StoreGateSvc.h:128
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Geo2G4AssemblyVolume::AddPlacedVolume
void AddPlacedVolume(G4LogicalVolume *pPlacedVolume, G4ThreeVector &translation, G4RotationMatrix *rotation, int copyNo=0, const G4String &userComment="")
Definition: Geo2G4AssemblyVolume.cxx:72
ExtParameterisedVolumeBuilder::getMatEther
void getMatEther()
Definition: ExtParameterisedVolumeBuilder.cxx:261
Geo2G4STParameterisation.h
beamspotman.n
n
Definition: beamspotman.py:731
ExtParameterisedVolumeBuilder.h
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
CLHEPtoEigenConverter.h
StoredMaterialManager.h
ExtParameterisedVolumeBuilder::ExtParameterisedVolumeBuilder
ExtParameterisedVolumeBuilder(const std::string &n, Geo2G4AssemblyFactory *G4AssemblyFactory)
Definition: ExtParameterisedVolumeBuilder.cxx:31
Geo2G4AssemblyVolume
Definition: Geo2G4AssemblyVolume.h:16
Geo2G4AssemblyVolume::AddPlacedAssembly
void AddPlacedAssembly(Geo2G4AssemblyVolume *pAssembly, G4Transform3D &transformation)
Definition: Geo2G4AssemblyVolume.cxx:132
Geo2G4AssemblyFactory
Definition: Geo2G4AssemblyFactory.h:16
VolumeBuilder::m_paramOn
bool m_paramOn
Definition: Simulation/G4Utilities/Geo2G4/src/VolumeBuilder.h:39
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
Geo2G4LVFactory
Definition: Geo2G4LVFactory.h:15
StoreGateSvc.h
Geo2G4LVFactory.h