35 std::unordered_map<std::string, G4Volume*>* g4s) {
50 thisG4Volume->setSolidPlacement(*rot,
getPosition(s));
55 if (thisG4Volume->getSolid() !=
nullptr)
return thisG4Volume->getSolid();
61 auto volume_copy =
gsystem +
"/" + copyOf;
63 if (thisG4Volume->getSolid() !=
nullptr)
return thisG4Volume->getSolid();
70 if (solidOperations.size() == 3) {
71 auto resolveOperandName = [s, g4s](
const std::string& operand) -> std::string {
76 auto leftName = resolveOperandName(solidOperations[0]);
77 auto rightName = resolveOperandName(solidOperations[2]);
80 if (left ==
nullptr || right ==
nullptr)
return nullptr;
86 G4RotationMatrix rotate = rightWrapper->getSolidRotation();
87 G4ThreeVector translate = rightWrapper->getSolidTranslation();
88 G4RotationMatrix invRot = rotate.invert();
89 G4Transform3D transf1(invRot, G4ThreeVector(0, 0, 0));
90 G4Transform3D transf2(G4RotationMatrix(), translate);
91 G4Transform3D transform = transf2 * transf1;
93 if (solidOperations[1] ==
"+") {
94 thisG4Volume->setSolid(
new G4UnionSolid(g4name, left, right, transform),
log);
96 else if (solidOperations[1] ==
"-") {
97 thisG4Volume->setSolid(
new G4SubtractionSolid(g4name, left, right, transform),
log);
99 else if (solidOperations[1] ==
"*") {
100 thisG4Volume->setSolid(
new G4IntersectionSolid(g4name, left, right, transform),
log);
104 "The boolean constructor of <", g4name,
"> uses unsupported operator <",
105 solidOperations[1],
">. Use +, -, or *.");
107 return thisG4Volume->getSolid();
110 "The boolean constructor of <", g4name,
"> must be: left operator right.");
117 std::string type = s->
getType();
119 if (type ==
"G4Box") {
120 thisG4Volume->setSolid(
new G4Box(g4name,
125 return thisG4Volume->getSolid();
127 else if (type ==
"G4Tubs") {
128 thisG4Volume->setSolid(
new G4Tubs(g4name,
135 return thisG4Volume->getSolid();
137 else if (type ==
"G4Sphere") {
138 thisG4Volume->setSolid(
new G4Sphere(g4name,
146 return thisG4Volume->getSolid();
148 else if (type ==
"G4Torus") {
149 thisG4Volume->setSolid(
new G4Torus(g4name,
156 return thisG4Volume->getSolid();
158 else if (type ==
"G4CutTubs") {
159 thisG4Volume->setSolid(
new G4CutTubs(g4name,
165 G4ThreeVector(pars[5], pars[6], pars[7]),
166 G4ThreeVector(pars[8], pars[9], pars[10])
168 return thisG4Volume->getSolid();
170 else if (type ==
"G4Cons") {
171 thisG4Volume->setSolid(
new G4Cons(g4name,
180 return thisG4Volume->getSolid();
182 else if (type ==
"G4Para") {
183 thisG4Volume->setSolid(
new G4Para(g4name,
194 return thisG4Volume->getSolid();
196 else if (type ==
"G4Trd") {
197 thisG4Volume->setSolid(
new G4Trd(g4name,
204 return thisG4Volume->getSolid();
206 else if (type ==
"G4Trap") {
208 if (pars.size() == 4) {
209 thisG4Volume->setSolid(
new G4Trap(g4name,
216 else if (pars.size() == 11) {
217 thisG4Volume->setSolid(
new G4Trap(g4name,
232 else if (pars.size() == 24) {
234 pt[0] = G4ThreeVector(pars[0], pars[1], pars[2]);
235 pt[1] = G4ThreeVector(pars[3], pars[4], pars[5]);
236 pt[2] = G4ThreeVector(pars[6], pars[7], pars[8]);
237 pt[3] = G4ThreeVector(pars[9], pars[10], pars[11]);
238 pt[4] = G4ThreeVector(pars[12], pars[13], pars[14]);
239 pt[5] = G4ThreeVector(pars[15], pars[16], pars[17]);
240 pt[6] = G4ThreeVector(pars[18], pars[19], pars[20]);
241 pt[7] = G4ThreeVector(pars[21], pars[22], pars[23]);
243 thisG4Volume->setSolid(
new G4Trap(g4name, pt),
log);
247 "The constructor of <", g4name,
"> must have 4, 11 or 24 parameters",
248 " see https://geant4-userdoc.web.cern.ch/UsersGuides/ForApplicationDeveloper/html/Detector/Geometry/geomSolids.html");
250 return thisG4Volume->getSolid();
252 else if (type ==
"G4Polycone") {
253 double phistart = pars[0];
254 double phitotal = pars[1];
255 int zplanes =
static_cast<int>(pars[2]);
258 auto zPlane = std::make_unique<double[]>(zplanes);
259 auto rInner = std::make_unique<double[]>(zplanes);
260 auto rOuter = std::make_unique<double[]>(zplanes);
262 for (
int zpl = 0; zpl < zplanes; ++zpl) {
263 zPlane[zpl] = pars[3 + 0 * zplanes + zpl];
264 rInner[zpl] = pars[3 + 1 * zplanes + zpl];
265 rOuter[zpl] = pars[3 + 2 * zplanes + zpl];
268 thisG4Volume->setSolid(
new G4Polycone(g4name,
276 return thisG4Volume->getSolid();
278 else if (type ==
"G4Polyhedra") {
281 double phistart = pars[0];
282 double phitotal = pars[1];
283 int numSides =
static_cast<int>(pars[2]);
284 int zplanes =
static_cast<int>(pars[3]);
286 if (numSides < 1 ||
static_cast<int>(pars.size()) != 4 + 3 * zplanes) {
288 "The constructor of <", g4name,
"> must have numSides >= 1 and ",
289 4 + 3 * zplanes,
" parameters (4 + 3 x numZPlanes), we got ", pars.size());
293 auto zPlane = std::make_unique<double[]>(zplanes);
294 auto rInner = std::make_unique<double[]>(zplanes);
295 auto rOuter = std::make_unique<double[]>(zplanes);
297 for (
int zpl = 0; zpl < zplanes; ++zpl) {
298 rInner[zpl] = pars[4 + 0 * zplanes + zpl];
299 rOuter[zpl] = pars[4 + 1 * zplanes + zpl];
300 zPlane[zpl] = pars[4 + 2 * zplanes + zpl];
303 thisG4Volume->setSolid(
new G4Polyhedra(g4name,
312 return thisG4Volume->getSolid();
314 else if (type ==
"G4Paraboloid") {
315 thisG4Volume->setSolid(
new G4Paraboloid(g4name,
320 return thisG4Volume->getSolid();
322 else if (type ==
"G4EllipticalTube") {
323 thisG4Volume->setSolid(
new G4EllipticalTube(g4name,
328 return thisG4Volume->getSolid();
332 "The constructor of <", g4name,
"> uses an unknown solid type <", type,
333 ">. See Geant4 manual for supported primitives.");