1#include "SimCore/Geo/AuxInfoReader.h"
6#include "Framework/Exception/Exception.h"
13#include "G4FieldManager.hh"
14#include "G4GDMLEvaluator.hh"
15#include "G4LogicalVolumeStore.hh"
17#include "G4RegionStore.hh"
18#include "G4SDManager.hh"
19#include "G4SystemOfUnits.hh"
20#include "G4UniformMagField.hh"
28namespace simcore::geo {
32 : parser_(theParser), eval_(new G4GDMLEvaluator) {}
40 const G4GDMLAuxListType* aux_info_list =
parser_->GetAuxList();
41 for (
const auto& aux_info : *aux_info_list) {
42 G4String aux_type = aux_info.type;
43 G4String aux_val = aux_info.value;
45 if (aux_type ==
"SensDet") {
47 <<
"[ WARN ] : Not defining SensDet in GDML since v1.0 of SimCore. "
48 "See https://github.com/LDMX-Software/SimCore/issues/39"
50 }
else if (aux_type ==
"MagneticField") {
52 }
else if (aux_type ==
"Region") {
54 }
else if (aux_type ==
"VisAttributes") {
56 }
else if (aux_type ==
"DetectorVersion") {
64 const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
65 std::vector<G4LogicalVolume*>::const_iterator lvciter;
66 for (lvciter = lvs->begin(); lvciter != lvs->end(); lvciter++) {
67 G4GDMLAuxListType aux_info_list =
68 parser_->GetVolumeAuxiliaryInformation(*lvciter);
70 for (
const auto& aux_info : aux_info_list) {
71 G4String aux_type = aux_info.type;
72 G4String aux_val = aux_info.value;
74 G4LogicalVolume* lv = (*lvciter);
76 if (aux_type ==
"MagneticField") {
77 const G4String& mag_field_name = aux_val;
78 G4MagneticField* mag_field =
80 if (mag_field !=
nullptr) {
81 auto mgr =
new G4FieldManager(mag_field);
90 "Unknown MagneticField ref in volume's auxiliary info: " +
91 std::string(mag_field_name.data()));
93 }
else if (aux_type ==
"Region") {
94 const G4String& region_name = aux_val;
95 G4Region* region = G4RegionStore::GetInstance()->GetRegion(region_name);
96 if (region !=
nullptr) {
97 region->AddRootLogicalVolume(lv);
101 EXCEPTION_RAISE(
"MissingInfo",
"Reference region '" +
102 std::string(region_name.data()) +
105 }
else if (aux_type ==
"VisAttributes") {
106 const G4String& vis_name = aux_val;
107 G4VisAttributes* vis_attributes =
109 if (vis_attributes !=
nullptr) {
110 lv->SetVisAttributes(vis_attributes);
114 EXCEPTION_RAISE(
"MissingInfo",
"Referenced VisAttributes '" +
115 std::string(vis_name.data()) +
124 const G4GDMLAuxListType* auxInfoList) {
126 G4String mag_field_type(
"");
127 for (
const auto& aux_info : *auxInfoList) {
128 G4String aux_type = aux_info.type;
129 G4String aux_val = aux_info.value;
131 if (aux_type ==
"MagneticFieldType") {
132 mag_field_type = aux_val;
137 if (mag_field_type ==
"") {
138 EXCEPTION_RAISE(
"MissingInfo",
139 "Missing MagFieldType for magnetic field definition.");
142 G4MagneticField* mag_field =
nullptr;
145 if (mag_field_type ==
"G4UniformMagField") {
148 for (
const auto& aux_info : *auxInfoList) {
149 G4String aux_type = aux_info.type;
150 G4String aux_val = aux_info.value;
151 G4String aux_unit = aux_info.unit;
153 G4String expr = aux_val +
"*" + aux_unit;
154 if (aux_type ==
"bx") {
155 bx =
eval_->Evaluate(expr);
156 }
else if (aux_type ==
"by") {
157 by =
eval_->Evaluate(expr);
158 }
else if (aux_type ==
"bz") {
159 bz =
eval_->Evaluate(expr);
162 G4ThreeVector field_components(bx, by, bz);
163 mag_field =
new G4UniformMagField(field_components);
169 }
else if (mag_field_type ==
"MagneticFieldMap3D") {
175 for (
const auto& aux_info : *auxInfoList) {
176 G4String aux_type = aux_info.type;
177 G4String aux_val = aux_info.value;
178 G4String aux_unit = aux_info.unit;
180 G4String expr = aux_val +
"*" + aux_unit;
182 if (aux_type ==
"File") {
184 }
else if (aux_type ==
"OffsetX") {
185 offset_x =
eval_->Evaluate(expr);
186 }
else if (aux_type ==
"OffsetY") {
187 offset_y =
eval_->Evaluate(expr);
188 }
else if (aux_type ==
"OffsetZ") {
189 offset_z =
eval_->Evaluate(expr);
193 if (file_name.size() == 0) {
194 EXCEPTION_RAISE(
"MissingInfo",
195 "File info with field data was not provided.");
203 G4FieldManager* field_mgr =
204 G4TransportationManager::GetTransportationManager()->GetFieldManager();
205 if (field_mgr->GetDetectorField() !=
nullptr) {
206 EXCEPTION_RAISE(
"MisAssign",
"Global mag field was already assigned.");
208 field_mgr->SetDetectorField(mag_field);
209 field_mgr->CreateChordFinder(mag_field);
212 EXCEPTION_RAISE(
"UnknownType",
"Unknown MagFieldType '" +
213 std::string(mag_field_type.data()) +
214 "' in auxiliary info.");
221 const G4GDMLAuxListType* auxInfoList) {
222 bool store_trajectories =
true;
223 for (
const auto& aux_info : *auxInfoList) {
224 G4String aux_type = aux_info.type;
225 G4String aux_val = aux_info.value;
227 if (aux_type ==
"StoreTrajectories") {
228 if (aux_val ==
"false") {
229 store_trajectories =
false;
230 }
else if (aux_val ==
"true") {
231 store_trajectories =
true;
235 G4VUserRegionInformation* region_info =
245 auto region =
new G4Region(name);
246 region->SetUserInformation(region_info);
251 const G4GDMLAuxListType* auxInfoList) {
252 std::array<G4double, 4> rgba = {1., 1., 1., 1.};
253 G4bool visible =
true;
254 G4bool dau_invisible =
false;
255 G4bool force_wireframe =
false;
256 G4bool force_solid =
false;
257 G4double line_width = 1.0;
258 G4VisAttributes::LineStyle line_style = G4VisAttributes::unbroken;
260 for (
const auto& aux_info : *auxInfoList) {
261 G4String aux_type = aux_info.type;
262 G4String aux_val = aux_info.value;
264 if (aux_type ==
"R") {
265 rgba[0] = atof(aux_val.c_str());
266 }
else if (aux_type ==
"G") {
267 rgba[1] = atof(aux_val.c_str());
268 }
else if (aux_type ==
"B") {
269 rgba[2] = atof(aux_val.c_str());
270 }
else if (aux_type ==
"A") {
271 rgba[3] = atof(aux_val.c_str());
272 }
else if (aux_type ==
"Style") {
273 if (aux_val ==
"wireframe") {
274 force_wireframe =
true;
275 }
else if (aux_val ==
"solid") {
278 }
else if (aux_type ==
"DaughtersInvisible") {
279 if (aux_val ==
"true") {
280 dau_invisible =
true;
281 }
else if (aux_val ==
"false") {
282 dau_invisible =
false;
284 }
else if (aux_type ==
"Visible") {
285 if (aux_val ==
"true") {
287 }
else if (aux_val ==
"false") {
290 }
else if (aux_type ==
"LineStyle") {
291 if (aux_val ==
"unbroken") {
292 line_style = G4VisAttributes::unbroken;
293 }
else if (aux_val ==
"dashed") {
294 line_style = G4VisAttributes::dashed;
295 }
else if (aux_val ==
"dotted") {
296 line_style = G4VisAttributes::dotted;
298 }
else if (aux_type ==
"LineWidth") {
299 line_width = atof(aux_val.c_str());
303 auto vis_attributes =
new G4VisAttributes();
304 vis_attributes->SetColor(rgba[0], rgba[1], rgba[2], rgba[3]);
305 vis_attributes->SetVisibility(visible);
306 vis_attributes->SetDaughtersInvisible(dau_invisible);
307 vis_attributes->SetForceWireframe(force_wireframe);
308 vis_attributes->SetForceSolid(force_solid);
309 vis_attributes->SetLineWidth(line_width);
310 vis_attributes->SetLineStyle(line_style);
318 const G4GDMLAuxListType* auxInfoList) {
319 int detector_version = atoi(auxValue.c_str());
321 std::string detector_name(
"");
322 std::string author(
"");
323 std::string description(
"");
325 for (
const auto& aux_info : *auxInfoList) {
326 G4String aux_type = aux_info.type;
327 G4String aux_val = aux_info.value;
329 if (aux_type ==
"DetectorName") {
330 detector_name = aux_val;
331 }
else if (aux_type ==
"Author") {
333 }
else if (aux_type ==
"Description") {
334 description = aux_val;
339 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 * detector_header_
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.