g4system
Loading...
Searching...
No Matches
g4objectsFactory.cc
Go to the documentation of this file.
1
11#include "g4objectsFactory.h"
12
13#include "gutilities.h"
14#include "gsystemConventions.h"
16
17// Geant4
18#include "G4LogicalVolumeStore.hh"
19#include "G4Material.hh"
20#include "G4NistManager.hh"
21#include "G4PVPlacement.hh"
22
23// c++
24#include <string_view>
25
26// Configure factory behavior (overlap checking + backup material).
28 const std::string &backup_mat) {
29 checkOverlaps = check_overlaps;
30 backupMaterial = backup_mat;
31}
32
33// Convenience: retrieve the solid pointer for a named volume from the wrapper map.
34G4VSolid *G4ObjectsFactory::getSolidFromMap(const std::string &vname,
35 std::unordered_map<std::string, G4Volume *> *g4s) {
36 auto it = g4s->find(vname);
37 return (it != g4s->end()) ? it->second->getSolid() : nullptr;
38}
39
40// Convenience: retrieve the logical pointer for a named volume from the wrapper map.
41G4LogicalVolume *G4ObjectsFactory::getLogicalFromMap(const std::string &volume_name,
42 std::unordered_map<std::string, G4Volume *> *g4s) {
43 auto it = g4s->find(volume_name);
44 return (it != g4s->end()) ? it->second->getLogical() : nullptr;
45}
46
47// Convenience: retrieve the physical pointer for a named volume from the wrapper map.
48G4VPhysicalVolume *G4ObjectsFactory::getPhysicalFromMap(const std::string &vname,
49 std::unordered_map<std::string, G4Volume *> *g4s) {
50 auto it = g4s->find(vname);
51 return (it != g4s->end()) ? it->second->getPhysical() : nullptr;
52}
53
55 // Convert GEMC color + opacity into a Geant4 color. The helper returns a \c G4Colour.
56 std::string_view color = s->getColor();
57 double opacity = s->getOpacity();
58
59 const auto g4color = gutilities::makeG4Colour(color, opacity);
60
61 log->info(2, className(), " createVisualAttributes for color ", color,
62 " resulted in RGB = (", g4color.GetRed(), ", ", g4color.GetGreen(), ", ", g4color.GetBlue(),
63 ", opacity: ", opacity, ")");
64
65 G4VisAttributes attr(g4color);
66
67 // Visibility and style flags are stored on the volume definition.
68 s->isVisible() ? attr.SetVisibility(true) : attr.SetVisibility(false);
69
70 switch (s->getStyle()) {
71 case 0:
72 attr.SetForceWireframe(true);
73 break;
74 case 1:
75 attr.SetForceSolid(true);
76 break;
77 case 2:
78 attr.SetForceCloud(true);
79 break;
80 default:
81 break;
82 }
83
84
85 return attr;
86}
87
88G4RotationMatrix *G4ObjectsFactory::getRotation(const GVolume *s) {
89 // Parse a rotation string expressed as three angles and apply them in X/Y/Z order.
90 auto rot = new G4RotationMatrix();
91
93 if (rotDef.size() == 3) {
94 const auto pars = gutilities::getG4NumbersFromStringVector(rotDef);
95 rot->rotateX(pars[0]);
96 rot->rotateY(pars[1]);
97 rot->rotateZ(pars[2]);
98 }
99 // (ordered rotation parsing omitted for brevity – keep original logic)
100 return rot;
101}
102
103G4ThreeVector G4ObjectsFactory::getPosition(const GVolume *s) {
104 // Base placement position.
105 G4ThreeVector pos(0., 0., 0.);
106 const auto vec = gutilities::getG4NumbersFromString(s->getPos());
107 if (vec.size() == 3) pos.set(vec[0], vec[1], vec[2]);
108
109 // Optional shift modifier (applied after parsing the base position).
110 if (s->getShift() != GSYSTEMNOMODIFIER) {
111 const auto shift = gutilities::getG4NumbersFromString(s->getShift());
112 if (shift.size() == 3) pos += G4ThreeVector(shift[0], shift[1], shift[2]);
113 }
114 return pos;
115}
116
117G4LogicalVolume *G4ObjectsFactory::buildLogical(const GVolume *s,
118 std::unordered_map<std::string, G4Volume *> *g4s) {
119 const std::string g4name = s->getG4Name();
120 auto thisG4Volume = getOrCreateG4Volume(g4name, g4s);
121
122 // Logical exists, return it.
123 if (thisG4Volume->getLogical()) return thisG4Volume->getLogical();
124
125 // If this volume is a "copy of" another, reuse the logical volume if it already exists.
126 std::string copyOf = s->getCopyOf();
127 if (copyOf != "" && copyOf != UNINITIALIZEDSTRINGQUANTITY) {
128 auto gsystem = s->getSystem();
129 auto volume_copy = gsystem + "/" + copyOf;
130 auto copyG4Volume = getOrCreateG4Volume(volume_copy, g4s);
131 if (copyG4Volume->getLogical() != nullptr) {
132 return copyG4Volume->getLogical();
133 }
134 }
135
136 // Material lookup:
137 // - first try requested material
138 // - if missing and a backup material was configured, fall back to it
139 auto *nist = G4NistManager::Instance();
140 auto *mat = nist->FindOrBuildMaterial(s->getMaterial());
141 if (!mat && !backupMaterial.empty()) {
142 mat = nist->FindOrBuildMaterial(backupMaterial);
143 log->warning("Material <", s->getMaterial(), "> not found. Using backup material <", backupMaterial, ">.");
144 }
145
146 if (!mat) {
148 "Material <", s->getMaterial(), "> not found.");
149 }
150
151 // Create the logical volume with the already-created solid.
152 auto *logical = new G4LogicalVolume(thisG4Volume->getSolid(),
153 mat, g4name);
154
155 // Apply visualization attributes (color/opacity/visibility/style).
156 logical->SetVisAttributes(createVisualAttributes(s));
157 thisG4Volume->setLogical(logical, log);
158 return logical;
159}
160
161G4VPhysicalVolume *G4ObjectsFactory::buildPhysical(const GVolume *s,
162 std::unordered_map<std::string, G4Volume *> *g4s) {
163 // Nonexistent volumes are ignored by design.
164 if (!s->getExistence()) return nullptr;
165
166 // Mother/logical prerequisites must exist; otherwise caller will retry later.
167 if (!checkPhysicalDependencies(s, g4s)) return nullptr;
168
169 const std::string g4name = s->getG4Name();
170 auto thisG4Volume = getOrCreateG4Volume(g4name, g4s);
171 auto logicalVolume = thisG4Volume->getLogical();
172
173 // If this is a copy, reuse the source logical volume when available.
174 std::string copyOf = s->getCopyOf();
175 if (copyOf != "" && copyOf != UNINITIALIZEDSTRINGQUANTITY) {
176 auto gsystem = s->getSystem();
177 auto volume_copy = gsystem + "/" + copyOf;
178 auto copyG4Volume = getOrCreateG4Volume(volume_copy, g4s);
179 if (copyG4Volume->getLogical() != nullptr) {
180 logicalVolume = copyG4Volume->getLogical();
181 }
182 }
183
184 // Create the placement only once; subsequent calls return the cached physical volume.
185 if (!thisG4Volume->getPhysical()) {
186 G4RotationMatrix rotation_instance = *getRotation(s);
187 G4ThreeVector translation_instance = getPosition(s);
188
189 thisG4Volume->setPhysical(new G4PVPlacement(G4Transform3D(rotation_instance, translation_instance),
190 logicalVolume,
191 g4name,
193 false,
194 s->getPCopyNo(),
195 checkOverlaps > 0),
196 log);
197 }
198 return thisG4Volume->getPhysical();
199}
200
202 std::unordered_map<std::string, G4Volume *> *g4s) {
203 const auto name = s->getG4Name();
204
205 // Build steps can fail due to missing dependencies; each returns nullptr in that case.
206 auto sbuild = buildSolid(s, g4s);
207 auto lbuild = buildLogical(s, g4s);
208 auto pbuild = buildPhysical(s, g4s);
209
210 const bool okSolid = (sbuild != nullptr);
211 const bool okLogical = (lbuild != nullptr);
212 const bool okPhysical = (pbuild != nullptr);
213 const bool okAll = okSolid && okLogical && okPhysical;
214
215 log->info(2, className(), " result for ",
216 name,
217 ": solid: ", okSolid,
218 " logical: ", okLogical,
219 " physical: ", okPhysical);
220
221 return okAll;
222}
G4Volume * getOrCreateG4Volume(const std::string &volume_name, std::unordered_map< std::string, G4Volume * > *g4s)
Get or create a G4Volume wrapper entry in the map.
virtual G4LogicalVolume * buildLogical(const GVolume *s, std::unordered_map< std::string, G4Volume * > *g4s)
Build or retrieve the G4LogicalVolume for a volume.
virtual G4VPhysicalVolume * buildPhysical(const GVolume *s, std::unordered_map< std::string, G4Volume * > *g4s)
Build or retrieve the G4VPhysicalVolume for a volume.
static G4VPhysicalVolume * getPhysicalFromMap(const std::string &volume_name, std::unordered_map< std::string, G4Volume * > *g4s)
Lookup physical volume in the g4s map.
bool build_g4volume(const GVolume *s, std::unordered_map< std::string, G4Volume * > *g4s)
Build (or retrieve) solid, logical, and physical volumes for a given GVolume.
static G4RotationMatrix * getRotation(const GVolume *s)
Parse rotation string and build a Geant4 rotation matrix.
virtual std::string_view className() const =0
Short, human-readable factory name for logging.
virtual G4VSolid * buildSolid(const GVolume *s, std::unordered_map< std::string, G4Volume * > *g4s)=0
Build the G4VSolid for a volume.
bool checkPhysicalDependencies(const GVolume *s, std::unordered_map< std::string, G4Volume * > *g4s)
Verify prerequisites to build a physical placement.
static G4VSolid * getSolidFromMap(const std::string &volume_name, std::unordered_map< std::string, G4Volume * > *g4s)
Lookup solid in the g4s map.
static G4LogicalVolume * getLogicalFromMap(const std::string &volume_name, std::unordered_map< std::string, G4Volume * > *g4s)
Lookup logical volume in the g4s map.
void initialize_context(int checkOverlaps, const std::string &backupMaterial)
Configure overlap checking and backup material behavior for this factory.
static G4ThreeVector getPosition(const GVolume *s)
Parse position and optional shift strings to compute placement translation.
G4VisAttributes createVisualAttributes(const GVolume *s)
Build visualization attributes from the volume definition.
std::string backupMaterial
Backup material name used if the requested material is absent.
std::shared_ptr< GLogger > log
void warning(Args &&... args) const
void info(int level, Args &&... args) const
void error(int exit_code, Args &&... args) const
std::string getRot() const
std::string getCopyOf() const
bool getExistence() const
std::string getPos() const
int getPCopyNo() const
std::string getShift() const
std::string getMaterial() const
std::string getG4Name() const
std::string getSystem() const
int getStyle() const
bool isVisible() const
std::string_view getColor() const
double getOpacity() const
std::string getG4MotherName() const
Abstract factory that converts a GEMC DB GVolume into Geant4 objects.
Conventions, labels, and error codes used by the g4system geometry/material layer.
#define ERR_G4MATERIALNOTFOUND
Material lookup failed and no fallback was available.
#define GSYSTEMNOMODIFIER
#define UNINITIALIZEDSTRINGQUANTITY
vector< double > getG4NumbersFromString(const string &vstring, bool warnIfNotUnit=false)
vector< string > getStringVectorFromStringWithDelimiter(const string &input, const string &x)
G4Colour makeG4Colour(std::string_view code, double opacity)
vector< double > getG4NumbersFromStringVector(const vector< string > &vstring, bool warnIfNotUnit=false)