g4system
Loading...
Searching...
No Matches
buildSolid.cc
Go to the documentation of this file.
1
7// g4system
10
11// geant4
12#include "G4Box.hh"
13#include "G4Sphere.hh"
14#include "G4Tubs.hh"
15#include "G4CutTubs.hh"
16#include "G4Cons.hh"
17#include "G4Para.hh"
18#include "G4Trap.hh"
19#include "G4Trd.hh"
20#include "G4Polycone.hh"
21
22// Build a native Geant4 solid for the given volume definition.
23// Header documentation is authoritative; this implementation comment is intentionally brief.
25 std::unordered_map<std::string, G4Volume*>* g4s) {
26 std::string g4name = s->getG4Name();
27
28 log->info(2, className(), "G4NativeSystemFactory::buildSolid for ", g4name);
29
30 // Dependencies must be satisfied before constructing a solid (copy/boolean operands).
31 if (!checkSolidDependencies(s, g4s)) return nullptr;
32
33 // Locate or allocate the wrapper used to cache solid/logical/physical pointers.
34 auto thisG4Volume = getOrCreateG4Volume(g4name, g4s);
35
36 // Solid exists, return it.
37 if (thisG4Volume->getSolid() != nullptr) return thisG4Volume->getSolid();
38
39 // If this is a copy, reuse the source solid if available.
40 std::string copyOf = s->getCopyOf();
41 if (copyOf != "" && copyOf != UNINITIALIZEDSTRINGQUANTITY) {
42 auto gsystem = s->getSystem();
43 auto volume_copy = gsystem + "/" + copyOf;
44 auto thisG4Volume = getOrCreateG4Volume(volume_copy, g4s);
45 if (thisG4Volume->getSolid() != nullptr) return thisG4Volume->getSolid();
46 }
47
48 // Parse and validate parameters for the requested primitive.
49 std::vector<double> pars = checkAndReturnParameters(s);
50
51 std::string type = s->getType();
52
53 if (type == "G4Box") {
54 thisG4Volume->setSolid(new G4Box(g4name, // name
55 pars[0], // half-length in X
56 pars[1], // half-length in Y
57 pars[2] // half-length in Z
58 ), log);
59 return thisG4Volume->getSolid();
60 }
61 else if (type == "G4Tubs") {
62 thisG4Volume->setSolid(new G4Tubs(g4name, // name
63 pars[0], // Inner radius
64 pars[1], // Outer radius
65 pars[2], // half-length in z
66 pars[3], // Starting phi angle
67 pars[4] // Delta Phi angle
68 ), log);
69 return thisG4Volume->getSolid();
70 }
71 else if (type == "G4Sphere") {
72 thisG4Volume->setSolid(new G4Sphere(g4name, // name
73 pars[0], // Inner radius
74 pars[1], // Outer radius
75 pars[2], // Starting phi angle
76 pars[3], // Delta Phi angle
77 pars[4], // Starting delta angle
78 pars[5] // Delta delta angle
79 ), log);
80 return thisG4Volume->getSolid();
81 }
82 else if (type == "G4CutTubs") {
83 thisG4Volume->setSolid(new G4CutTubs(g4name, // name
84 pars[0], // Inner radius
85 pars[1], // Outer radius
86 pars[2], // half-length in z
87 pars[3], // Starting phi angle
88 pars[4], // Delta Phi angle
89 G4ThreeVector(pars[5], pars[6], pars[7]), // Outside Normal at -z
90 G4ThreeVector(pars[8], pars[9], pars[10]) // Outside Normal at +z
91 ), log);
92 return thisG4Volume->getSolid();
93 }
94 else if (type == "G4Cons") {
95 thisG4Volume->setSolid(new G4Cons(g4name, // name
96 pars[0], // Inside radius at -pDz
97 pars[1], // Outside radius at -pDz
98 pars[2], // Inside radius at +pDz
99 pars[3], // Outside radius at +pDz
100 pars[4], // half-length in z
101 pars[5], // Starting phi angle
102 pars[6] // Delta Phi angle
103 ), log);
104 return thisG4Volume->getSolid();
105 }
106 else if (type == "G4Para") {
107 thisG4Volume->setSolid(new G4Para(g4name, // name
108 pars[0], // half-length in x
109 pars[1], // half-length in y
110 pars[2], // half-length in z
111 pars[3],
112 // Angle formed by the y axis and by the plane joining the center of the faces parallel to the z-x plane at -dy and +dy
113 pars[4],
114 // Polar angle of the line joining the center of the faces at -dz and +dz in z
115 pars[5]
116 // Azimuthal angle of the line joining the center of the faces at -dz and +dz in z
117 ), log);
118 return thisG4Volume->getSolid();
119 }
120 else if (type == "G4Trd") {
121 thisG4Volume->setSolid(new G4Trd(g4name, // name
122 pars[0], // Half-length along x at the surface positioned at -dz
123 pars[1], // Half-length along x at the surface positioned at +dz
124 pars[2], // Half-length along y at the surface positioned at -dz
125 pars[3], // Half-length along y at the surface positioned at +dz
126 pars[4] // Half-length along z axis
127 ), log);
128 return thisG4Volume->getSolid();
129 }
130 else if (type == "G4Trap") {
131 // G4Trap supports multiple constructor layouts; parameter count decides which one is used.
132 if (pars.size() == 4) {
133 thisG4Volume->setSolid(new G4Trap(g4name, // name
134 pars[0], // Length along Z
135 pars[1], // Length along Y
136 pars[2], // Length along X wider side
137 pars[3] // Length along X at the narrower side (plTX<=pX)
138 ), log);
139 }
140 else if (pars.size() == 11) {
141 thisG4Volume->setSolid(new G4Trap(g4name, // name
142 pars[0], // Half Z length - distance from the origin to the bases
143 pars[1],
144 // Polar angle of the line joining the center of the bases at -/+pDz
145 pars[2], // Azimuthal angle of the same line
146 pars[3], // Half Y length of the base at -pDz
147 pars[4], // Half Y length of the base at +pDz
148 pars[5], // Half X length at smaller Y of the base at -pDz
149 pars[6], // Half X length at bigger Y of the base at -pDz
150 pars[7], // Half X length at smaller Y of the base at +pDz
151 pars[8], // Half X length at bigger y of the base at +pDz
152 pars[9], // Angle between Y-axis and center line at -pDz
153 pars[10] // Angle between Y-axis and center line at +pDz
154 ), log);
155 }
156 else if (pars.size() == 24) {
157 G4ThreeVector pt[8];
158 pt[0] = G4ThreeVector(pars[0], pars[1], pars[2]);
159 pt[1] = G4ThreeVector(pars[3], pars[4], pars[5]);
160 pt[2] = G4ThreeVector(pars[6], pars[7], pars[8]);
161 pt[3] = G4ThreeVector(pars[9], pars[10], pars[11]);
162 pt[4] = G4ThreeVector(pars[12], pars[13], pars[14]);
163 pt[5] = G4ThreeVector(pars[15], pars[16], pars[17]);
164 pt[6] = G4ThreeVector(pars[18], pars[19], pars[20]);
165 pt[7] = G4ThreeVector(pars[21], pars[22], pars[23]);
166
167 thisG4Volume->setSolid(new G4Trap(g4name, pt), log);
168 }
169 else {
171 "The constructor of <", g4name, "> must have 4, 11 or 24 parameters",
172 " see https://geant4-userdoc.web.cern.ch/UsersGuides/ForApplicationDeveloper/html/Detector/Geometry/geomSolids.html");
173 }
174 return thisG4Volume->getSolid();
175 }
176 else if (type == "G4Polycone") {
177 double phistart = pars[0];
178 double phitotal = pars[1];
179 int zplanes = static_cast<int>(pars[2]);
180
181 // Allocate arrays (data is copied by G4Polycone during construction).
182 auto zPlane = std::make_unique<double[]>(zplanes);
183 auto rInner = std::make_unique<double[]>(zplanes);
184 auto rOuter = std::make_unique<double[]>(zplanes);
185
186 for (int zpl = 0; zpl < zplanes; ++zpl) {
187 zPlane[zpl] = pars[3 + 0 * zplanes + zpl];
188 rInner[zpl] = pars[3 + 1 * zplanes + zpl];
189 rOuter[zpl] = pars[3 + 2 * zplanes + zpl];
190 }
191
192 thisG4Volume->setSolid(new G4Polycone(g4name, // name
193 phistart, // Initial Phi starting angle
194 phitotal, // Total Phi angle
195 zplanes, // Number of z planes
196 zPlane.get(),
197 rInner.get(),
198 rOuter.get()
199 ), log);
200 return thisG4Volume->getSolid();
201 }
202 else {
204 "The constructor of <", g4name, "> uses an unknown solid type <", type,
205 ">. See Geant4 manual for supported primitives.");
206 }
207 return nullptr;
208}
std::string_view className() const override
Human-readable name used for logging.
std::vector< double > checkAndReturnParameters(const GVolume *s)
Validate the number of parameters for the given primitive and return them as numeric values.
G4VSolid * buildSolid(const GVolume *s, std::unordered_map< std::string, G4Volume * > *g4s) override
Create (or reuse) a native Geant4 solid based on the GVolume "type".
Definition buildSolid.cc:24
G4Volume * getOrCreateG4Volume(const std::string &volume_name, std::unordered_map< std::string, G4Volume * > *g4s)
Get or create a G4Volume wrapper entry in the map.
bool checkSolidDependencies(const GVolume *s, std::unordered_map< std::string, G4Volume * > *g4s)
Check whether all prerequisites to build a solid are satisfied.
std::shared_ptr< GLogger > log
void info(int level, Args &&... args) const
void error(int exit_code, Args &&... args) const
std::string getCopyOf() const
std::string getG4Name() const
std::string getSystem() const
std::string getType() const
Factory that builds Geant4 native primitive solids (G4Box, G4Cons, G4Trap, ...) from GEMC GVolume rec...
Conventions, labels, and error codes used by the g4system geometry/material layer.
#define ERR_G4PARAMETERSMISMATCH
Solid parameter count/format did not match expected constructors.
#define ERR_G4SOLIDTYPENOTFOUND
Requested solid type is not supported by the native factory.
#define UNINITIALIZEDSTRINGQUANTITY