1#include "SimCore/Geo/AuxInfoReader.h"
4#include "Framework/Exception/Exception.h"
11#include "G4FieldManager.hh"
12#include "G4GDMLEvaluator.hh"
13#include "G4LogicalVolumeStore.hh"
15#include "G4RegionStore.hh"
16#include "G4SDManager.hh"
17#include "G4SystemOfUnits.hh"
18#include "G4UniformMagField.hh"
26namespace simcore::geo {
30 : parser_(theParser), eval_(new G4GDMLEvaluator) {}
38 const G4GDMLAuxListType* auxInfoList =
parser_->GetAuxList();
39 for (
const auto& auxInfo : *auxInfoList) {
40 G4String auxType = auxInfo.type;
41 G4String auxVal = auxInfo.value;
43 if (auxType ==
"SensDet") {
45 <<
"[ WARN ] : Not defining SensDet in GDML since v1.0 of SimCore. "
46 "See https://github.com/LDMX-Software/SimCore/issues/39"
48 }
else if (auxType ==
"MagneticField") {
50 }
else if (auxType ==
"Region") {
52 }
else if (auxType ==
"VisAttributes") {
54 }
else if (auxType ==
"DetectorVersion") {
62 const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
63 std::vector<G4LogicalVolume*>::const_iterator lvciter;
64 for (lvciter = lvs->begin(); lvciter != lvs->end(); lvciter++) {
65 G4GDMLAuxListType auxInfoList =
66 parser_->GetVolumeAuxiliaryInformation(*lvciter);
68 for (
const auto& auxInfo : auxInfoList) {
69 G4String auxType = auxInfo.type;
70 G4String auxVal = auxInfo.value;
72 G4LogicalVolume* lv = (*lvciter);
74 if (auxType ==
"MagneticField") {
75 const G4String& magFieldName = auxVal;
76 G4MagneticField* magField =
78 if (magField !=
nullptr) {
79 auto mgr =
new G4FieldManager(magField);
88 "Unknown MagneticField ref in volume's auxiliary info: " +
89 std::string(magFieldName.data()));
91 }
else if (auxType ==
"Region") {
92 const G4String& regionName = auxVal;
93 G4Region* region = G4RegionStore::GetInstance()->GetRegion(regionName);
94 if (region !=
nullptr) {
95 region->AddRootLogicalVolume(lv);
99 EXCEPTION_RAISE(
"MissingInfo",
"Reference region '" +
100 std::string(regionName.data()) +
103 }
else if (auxType ==
"VisAttributes") {
104 const G4String& visName = auxVal;
105 G4VisAttributes* visAttributes =
107 if (visAttributes !=
nullptr) {
108 lv->SetVisAttributes(visAttributes);
112 EXCEPTION_RAISE(
"MissingInfo",
"Referenced VisAttributes '" +
113 std::string(visName.data()) +
122 const G4GDMLAuxListType* auxInfoList) {
124 G4String magFieldType(
"");
125 for (
const auto& auxInfo : *auxInfoList) {
126 G4String auxType = auxInfo.type;
127 G4String auxVal = auxInfo.value;
129 if (auxType ==
"MagneticFieldType") {
130 magFieldType = auxVal;
135 if (magFieldType ==
"") {
136 EXCEPTION_RAISE(
"MissingInfo",
137 "Missing MagFieldType for magnetic field definition.");
140 G4MagneticField* magField =
nullptr;
143 if (magFieldType ==
"G4UniformMagField") {
146 for (
const auto& auxInfo : *auxInfoList) {
147 G4String auxType = auxInfo.type;
148 G4String auxVal = auxInfo.value;
149 G4String auxUnit = auxInfo.unit;
151 G4String expr = auxVal +
"*" + auxUnit;
152 if (auxType ==
"bx") {
153 bx =
eval_->Evaluate(expr);
154 }
else if (auxType ==
"by") {
155 by =
eval_->Evaluate(expr);
156 }
else if (auxType ==
"bz") {
157 bz =
eval_->Evaluate(expr);
160 G4ThreeVector fieldComponents(bx, by, bz);
161 magField =
new G4UniformMagField(fieldComponents);
167 }
else if (magFieldType ==
"MagneticFieldMap3D") {
173 for (
const auto& auxInfo : *auxInfoList) {
174 G4String auxType = auxInfo.type;
175 G4String auxVal = auxInfo.value;
176 G4String auxUnit = auxInfo.unit;
178 G4String expr = auxVal +
"*" + auxUnit;
180 if (auxType ==
"File") {
182 }
else if (auxType ==
"OffsetX") {
183 offsetX =
eval_->Evaluate(expr);
184 }
else if (auxType ==
"OffsetY") {
185 offsetY =
eval_->Evaluate(expr);
186 }
else if (auxType ==
"OffsetZ") {
187 offsetZ =
eval_->Evaluate(expr);
191 if (fileName.size() == 0) {
192 EXCEPTION_RAISE(
"MissingInfo",
193 "File info with field data was not provided.");
201 G4FieldManager* fieldMgr =
202 G4TransportationManager::GetTransportationManager()->GetFieldManager();
203 if (fieldMgr->GetDetectorField() !=
nullptr) {
204 EXCEPTION_RAISE(
"MisAssign",
"Global mag field was already assigned.");
206 fieldMgr->SetDetectorField(magField);
207 fieldMgr->CreateChordFinder(magField);
210 EXCEPTION_RAISE(
"UnknownType",
"Unknown MagFieldType '" +
211 std::string(magFieldType.data()) +
212 "' in auxiliary info.");
219 const G4GDMLAuxListType* auxInfoList) {
220 bool storeTrajectories =
true;
221 for (
const auto& auxInfo : *auxInfoList) {
222 G4String auxType = auxInfo.type;
223 G4String auxVal = auxInfo.value;
225 if (auxType ==
"StoreTrajectories") {
226 if (auxVal ==
"false") {
227 storeTrajectories =
false;
228 }
else if (auxVal ==
"true") {
229 storeTrajectories =
true;
233 G4VUserRegionInformation* regionInfo =
243 auto region =
new G4Region(name);
244 region->SetUserInformation(regionInfo);
249 const G4GDMLAuxListType* auxInfoList) {
250 std::array<G4double, 4> rgba = {1., 1., 1., 1.};
251 G4bool visible =
true;
252 G4bool dauInvisible =
false;
253 G4bool forceWireframe =
false;
254 G4bool forceSolid =
false;
255 G4double lineWidth = 1.0;
256 G4VisAttributes::LineStyle lineStyle = G4VisAttributes::unbroken;
258 for (
const auto& auxInfo : *auxInfoList) {
259 G4String auxType = auxInfo.type;
260 G4String auxVal = auxInfo.value;
262 if (auxType ==
"R") {
263 rgba[0] = atof(auxVal.c_str());
264 }
else if (auxType ==
"G") {
265 rgba[1] = atof(auxVal.c_str());
266 }
else if (auxType ==
"B") {
267 rgba[2] = atof(auxVal.c_str());
268 }
else if (auxType ==
"A") {
269 rgba[3] = atof(auxVal.c_str());
270 }
else if (auxType ==
"Style") {
271 if (auxVal ==
"wireframe") {
272 forceWireframe =
true;
273 }
else if (auxVal ==
"solid") {
276 }
else if (auxType ==
"DaughtersInvisible") {
277 if (auxVal ==
"true") {
279 }
else if (auxVal ==
"false") {
280 dauInvisible =
false;
282 }
else if (auxType ==
"Visible") {
283 if (auxVal ==
"true") {
285 }
else if (auxVal ==
"false") {
288 }
else if (auxType ==
"LineStyle") {
289 if (auxVal ==
"unbroken") {
290 lineStyle = G4VisAttributes::unbroken;
291 }
else if (auxVal ==
"dashed") {
292 lineStyle = G4VisAttributes::dashed;
293 }
else if (auxVal ==
"dotted") {
294 lineStyle = G4VisAttributes::dotted;
296 }
else if (auxType ==
"LineWidth") {
297 lineWidth = atof(auxVal.c_str());
301 auto visAttributes =
new G4VisAttributes();
302 visAttributes->SetColor(rgba[0], rgba[1], rgba[2], rgba[3]);
303 visAttributes->SetVisibility(visible);
304 visAttributes->SetDaughtersInvisible(dauInvisible);
305 visAttributes->SetForceWireframe(forceWireframe);
306 visAttributes->SetForceSolid(forceSolid);
307 visAttributes->SetLineWidth(lineWidth);
308 visAttributes->SetLineStyle(lineStyle);
316 const G4GDMLAuxListType* auxInfoList) {
317 int detectorVersion = atoi(auxValue.c_str());
319 std::string detectorName(
"");
320 std::string author(
"");
321 std::string description(
"");
323 for (
const auto& auxInfo : *auxInfoList) {
324 G4String auxType = auxInfo.type;
325 G4String auxVal = auxInfo.value;
327 if (auxType ==
"DetectorName") {
328 detectorName = auxVal;
329 }
else if (auxType ==
"Author") {
331 }
else if (auxType ==
"Description") {
332 description = auxVal;
337 description, author);
Class for defining a global 3D magnetic field.
Class providing a global store to access magnetic field objects.
Class that provides a global visualization attributes store.
Class encapsulating parameters for configuring a processor.
A 3D B-field map defined as a grid of points with associated B-field values.
static MagneticFieldStore * getInstance()
Get the global instance of the magnetic field store.
G4MagneticField * getMagneticField(const std::string &name)
Get a magnetic field by name.
void addMagneticField(const std::string &name, G4MagneticField *magField)
Add a magnetic field by name.
G4VisAttributes * getVisAttributes(const std::string &name)
Get vis attributes by name.
void addVisAttributes(const std::string &name, G4VisAttributes *visAttributes)
Register a vis attributes by name.
static VisAttributesStore * getInstance()
Get the global instance of the store.
void createDetectorHeader(const G4String &detectorVersion, const G4GDMLAuxListType *auxInfoList)
Create the detector header from the global auxinfo.
virtual ~AuxInfoReader()
Class destructor.
void assignAuxInfoToVolumes()
Assign auxiliary info to volumes such as sensitive detectors.
void readGlobalAuxInfo()
Read the global auxiliary information from the auxinfo block.
AuxInfoReader(G4GDMLParser *parser, const framework::config::Parameters &ps)
Class constructor.
void createVisAttributes(const G4String &name, const G4GDMLAuxListType *auxInfoList)
Create visualization attributes from GDML data.
G4GDMLEvaluator * eval_
The GDML expression evaluator.
G4GDMLParser * parser_
The GDML parser.
ldmx::DetectorHeader * detectorHeader_
Detector header with name and version.
void createMagneticField(const G4String &name, const G4GDMLAuxListType *auxInfoList)
Create a magnetic field from GDML data.
void createRegion(const G4String &name, const G4GDMLAuxListType *auxInfoList)
Create a detector region from GDML data.