BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
BDSGeometryFactory.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2022.
4
5This file is part of BDSIM.
6
7BDSIM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published
9by the Free Software Foundation version 3 of the License.
10
11BDSIM is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#include "BDSDebug.hh"
20#include "BDSException.hh"
21#include "BDSSDEnergyDeposition.hh"
22#include "BDSGeometryExternal.hh"
23#include "BDSGeometryFactory.hh"
24#include "BDSGeometryFactoryBase.hh"
25#ifdef USE_GDML
26#include "BDSGeometryFactoryGDML.hh"
27#endif
28#include "BDSGeometryFactorySQL.hh"
29#include "BDSGeometryType.hh"
30#include "BDSSDType.hh"
31#include "BDSUtilities.hh"
32
33#include "G4String.hh"
34#include "G4Types.hh"
35
36#include <map>
37#include <string>
38#include <utility>
39
41
43{
44 if (!instance)
46 return instance;
47}
48
50{
51#ifdef USE_GDML
53#else
54 gdml = nullptr;
55#endif
57}
58
59BDSGeometryFactory::~BDSGeometryFactory()
60{
61 delete gdml;
62 delete sql;
63 for (auto& geom : storage)
64 {delete geom;}
65 instance = nullptr;
66}
67
69{
70 switch(type.underlying())
71 {
72#ifdef USE_GDML
73 case BDSGeometryType::gdml:
74 {return gdml; break;}
75#endif
76 case BDSGeometryType::mokka:
77 {return sql; break;}
78 default:
79 {
80 G4cout << "Unsupported factory type " << type;
81 return nullptr;
82 }
83 }
84}
85
87 const G4String& formatAndFileName,
88 std::map<G4String, G4Colour*>* colourMapping,
89 G4bool autoColour,
90 G4double suggestedLength,
91 G4double suggestedHorizontalWidth,
92 std::vector<G4String>* namedVacuumVolumes,
93 G4bool makeSensitive,
94 BDSSDType sensitivityType,
95 G4bool stripOuterVolumeAndMakeAssembly,
96 G4UserLimits* userLimitsToAttachToAllLVs,
97 G4bool dontReloadGeometry)
98{
99 std::pair<G4String, G4String> ff = BDS::SplitOnColon(formatAndFileName);
100 G4String fileName = BDS::GetFullPath(ff.second);
101
102 G4String searchName = fileName;
103 // If we strip the outer volume we're technically modifying the geometry
104 // and should prepare a unique load of it and cache that otherwise, we
105 // will get either the original or the stripped version only if we place
106 // the load the same geometry twice with/without stripping
107 if (stripOuterVolumeAndMakeAssembly)
108 {searchName += "_stripped";}
109
110 // we have this option to purposively not reload geometry uniquely for multiple
111 // instances by different component names - we need this sometimes, but we must
112 // use it cautiously knowing all the instances will be identical
113 // therefore we use a fixed nonsense name that someone is prevented from calling
114 // a component (because it's an option)
115 if (dontReloadGeometry)
116 {componentName = "dontReloadGeometry";}
117
118 auto nameAndField = std::make_pair(searchName, componentName);
119 const auto search = registry.find(nameAndField);
120 if (search != registry.end())
121 {return search->second;}// it was found already in registry
122 // else wasn't found so continue
123
124 // Check the file exists.
125 if (!BDS::FileExists(fileName))
126 {throw BDSException(__METHOD_NAME__, "No such file \"" + fileName + "\"");}
127
130 if (!factory)
131 {return nullptr;}
132
133 BDSGeometryExternal* result = factory->Build(componentName,
134 fileName,
135 colourMapping,
136 autoColour,
137 suggestedLength,
138 suggestedHorizontalWidth,
139 namedVacuumVolumes,
140 userLimitsToAttachToAllLVs);
141
142 if (result)
143 {
144 if (stripOuterVolumeAndMakeAssembly)
146 // Set all volumes to be sensitive.
147 if (makeSensitive)
148 {result->MakeAllVolumesSensitive(sensitivityType);}
149
150 // cache using optionally modified name
151 auto key = std::make_pair((std::string)searchName, componentName);
152 registry[key] = result;
153 storage.insert(result);
154 }
155
156 return result;
157}
General exception with possible name of object and message.
Definition: BDSException.hh:35
void MakeAllVolumesSensitive(BDSSDType stype=BDSSDType::energydep)
void StripOuterAndMakeAssemblyVolume()
Change from a container logical volume to an assembly volume.
A loaded piece of externally provided geometry.
Base class for external geometry loading factories.
virtual BDSGeometryExternal * Build(G4String componentName, G4String fileName, std::map< G4String, G4Colour * > *colourMapping=nullptr, G4bool autoColour=true, G4double suggestedLength=0, G4double suggestedHorizontalWidth=0, std::vector< G4String > *vacuumBiasVolumeNames=nullptr, G4UserLimits *userLimitsToAttachToAllLVs=nullptr)=0
Main method to load and construct geometry.
Interface to Geant4's GDML loader.
Geometry factory for SQL geometry.
Interface to external geometry construction.
static BDSGeometryFactory * Instance()
Singleton accessor.
static BDSGeometryFactory * instance
Singleton instance.
BDSGeometryExternal * BuildGeometry(G4String componentName, const G4String &formatAndFilePath, std::map< G4String, G4Colour * > *colourMapping=nullptr, G4bool autoColour=true, G4double suggestedLength=0, G4double suggestedHorizontalWidth=0, std::vector< G4String > *namedVacuumVolumes=nullptr, G4bool makeSensitive=true, BDSSDType sensitivityType=BDSSDType::energydep, G4bool stripOuterVolumeAndMakeAssembly=false, G4UserLimits *userLimitsToAttachToAllLVs=nullptr, G4bool dontReloadGeometry=false)
BDSGeometryFactoryBase * gdml
Factory instance.
std::map< std::pair< std::string, std::string >, BDSGeometryExternal * > registry
BDSGeometryFactoryBase * GetAppropriateFactory(BDSGeometryType type)
Get the appropriate geometry factory.
BDSGeometryFactory()
Private accessor as singleton.
std::set< BDSGeometryExternal * > storage
BDSGeometryFactoryBase * sql
Factory instance.
Improve type-safety of native enum data type in C++.
type underlying() const
return underlying value (can be used in switch statement)
std::pair< G4String, G4String > SplitOnColon(const G4String &formatAndPath)
BDSGeometryType DetermineGeometryType(G4String geometryType)
function that gives corresponding enum value for string (case-insensitive)
G4String GetFullPath(G4String filename, bool excludeNameFromPath=false, bool useCWDForPrefix=false)
G4bool FileExists(const G4String &filename)
Checks if filename exists.