1#include "SimCore/Geo/AuxInfoReader.h"
6#include "Framework/Exception/Exception.h"
13#include "G4FieldManager.hh"
14#include "G4GDMLEvaluator.hh"
15#include "G4LogicalVolumeStore.hh"
16#include "G4ProductionCuts.hh"
17#include "G4ProductionCutsTable.hh"
19#include "G4RegionStore.hh"
20#include "G4SDManager.hh"
21#include "G4SystemOfUnits.hh"
22#include "G4UniformMagField.hh"
30namespace simcore::geo {
34 : parser_(theParser), eval_(new G4GDMLEvaluator) {}
42 const G4GDMLAuxListType* aux_info_list =
parser_->GetAuxList();
43 for (
const auto& aux_info : *aux_info_list) {
44 G4String aux_type = aux_info.type;
45 G4String aux_val = aux_info.value;
47 if (aux_type ==
"SensDet") {
49 <<
"[ WARN ] : Not defining SensDet in GDML since v1.0 of SimCore. "
50 "See https://github.com/LDMX-Software/SimCore/issues/39"
52 }
else if (aux_type ==
"MagneticField") {
54 }
else if (aux_type ==
"Region") {
56 }
else if (aux_type ==
"VisAttributes") {
58 }
else if (aux_type ==
"DetectorVersion") {
66 const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
67 std::vector<G4LogicalVolume*>::const_iterator lvciter;
68 for (lvciter = lvs->begin(); lvciter != lvs->end(); lvciter++) {
69 G4GDMLAuxListType aux_info_list =
70 parser_->GetVolumeAuxiliaryInformation(*lvciter);
72 for (
const auto& aux_info : aux_info_list) {
73 G4String aux_type = aux_info.type;
74 G4String aux_val = aux_info.value;
76 G4LogicalVolume* lv = (*lvciter);
78 if (aux_type ==
"MagneticField") {
79 const G4String& mag_field_name = aux_val;
80 G4MagneticField* mag_field =
82 if (mag_field !=
nullptr) {
83 auto mgr =
new G4FieldManager(mag_field);
92 "Unknown MagneticField ref in volume's auxiliary info: " +
93 std::string(mag_field_name.data()));
95 }
else if (aux_type ==
"Region") {
96 const G4String& region_name = aux_val;
97 G4Region* region = G4RegionStore::GetInstance()->GetRegion(region_name);
98 if (region !=
nullptr) {
99 region->AddRootLogicalVolume(lv);
103 EXCEPTION_RAISE(
"MissingInfo",
"Reference region '" +
104 std::string(region_name.data()) +
107 }
else if (aux_type ==
"VisAttributes") {
108 const G4String& vis_name = aux_val;
109 G4VisAttributes* vis_attributes =
111 if (vis_attributes !=
nullptr) {
112 lv->SetVisAttributes(vis_attributes);
116 EXCEPTION_RAISE(
"MissingInfo",
"Referenced VisAttributes '" +
117 std::string(vis_name.data()) +
126 const G4GDMLAuxListType* auxInfoList) {
128 G4String mag_field_type(
"");
129 for (
const auto& aux_info : *auxInfoList) {
130 G4String aux_type = aux_info.type;
131 G4String aux_val = aux_info.value;
133 if (aux_type ==
"MagneticFieldType") {
134 mag_field_type = aux_val;
139 if (mag_field_type ==
"") {
140 EXCEPTION_RAISE(
"MissingInfo",
141 "Missing MagFieldType for magnetic field definition.");
144 G4MagneticField* mag_field =
nullptr;
147 if (mag_field_type ==
"G4UniformMagField") {
150 for (
const auto& aux_info : *auxInfoList) {
151 G4String aux_type = aux_info.type;
152 G4String aux_val = aux_info.value;
153 G4String aux_unit = aux_info.unit;
155 G4String expr = aux_val +
"*" + aux_unit;
156 if (aux_type ==
"bx") {
157 bx =
eval_->Evaluate(expr);
158 }
else if (aux_type ==
"by") {
159 by =
eval_->Evaluate(expr);
160 }
else if (aux_type ==
"bz") {
161 bz =
eval_->Evaluate(expr);
164 G4ThreeVector field_components(bx, by, bz);
165 mag_field =
new G4UniformMagField(field_components);
171 }
else if (mag_field_type ==
"MagneticFieldMap3D") {
177 for (
const auto& aux_info : *auxInfoList) {
178 G4String aux_type = aux_info.type;
179 G4String aux_val = aux_info.value;
180 G4String aux_unit = aux_info.unit;
182 G4String expr = aux_val +
"*" + aux_unit;
184 if (aux_type ==
"File") {
186 }
else if (aux_type ==
"OffsetX") {
187 offset_x =
eval_->Evaluate(expr);
188 }
else if (aux_type ==
"OffsetY") {
189 offset_y =
eval_->Evaluate(expr);
190 }
else if (aux_type ==
"OffsetZ") {
191 offset_z =
eval_->Evaluate(expr);
195 if (file_name.size() == 0) {
196 EXCEPTION_RAISE(
"MissingInfo",
197 "File info with field data was not provided.");
205 G4FieldManager* field_mgr =
206 G4TransportationManager::GetTransportationManager()->GetFieldManager();
207 if (field_mgr->GetDetectorField() !=
nullptr) {
208 EXCEPTION_RAISE(
"MisAssign",
"Global mag field was already assigned.");
210 field_mgr->SetDetectorField(mag_field);
211 field_mgr->CreateChordFinder(mag_field);
214 EXCEPTION_RAISE(
"UnknownType",
"Unknown MagFieldType '" +
215 std::string(mag_field_type.data()) +
216 "' in auxiliary info.");
223 const G4GDMLAuxListType* auxInfoList) {
224 bool store_trajectories =
true;
225 for (
const auto& aux_info : *auxInfoList) {
226 G4String aux_type = aux_info.type;
227 G4String aux_val = aux_info.value;
229 if (aux_type ==
"StoreTrajectories") {
230 if (aux_val ==
"false") {
231 store_trajectories =
false;
232 }
else if (aux_val ==
"true") {
233 store_trajectories =
true;
237 G4VUserRegionInformation* region_info =
247 auto region =
new G4Region(name);
248 region->SetUserInformation(region_info);
250 region->SetProductionCuts(G4ProductionCutsTable::GetProductionCutsTable()
251 ->GetDefaultProductionCuts());
256 const G4GDMLAuxListType* auxInfoList) {
257 std::array<G4double, 4> rgba = {1., 1., 1., 1.};
258 G4bool visible =
true;
259 G4bool dau_invisible =
false;
260 G4bool force_wireframe =
false;
261 G4bool force_solid =
false;
262 G4double line_width = 1.0;
263 G4VisAttributes::LineStyle line_style = G4VisAttributes::unbroken;
265 for (
const auto& aux_info : *auxInfoList) {
266 G4String aux_type = aux_info.type;
267 G4String aux_val = aux_info.value;
269 if (aux_type ==
"R") {
270 rgba[0] = atof(aux_val.c_str());
271 }
else if (aux_type ==
"G") {
272 rgba[1] = atof(aux_val.c_str());
273 }
else if (aux_type ==
"B") {
274 rgba[2] = atof(aux_val.c_str());
275 }
else if (aux_type ==
"A") {
276 rgba[3] = atof(aux_val.c_str());
277 }
else if (aux_type ==
"Style") {
278 if (aux_val ==
"wireframe") {
279 force_wireframe =
true;
280 }
else if (aux_val ==
"solid") {
283 }
else if (aux_type ==
"DaughtersInvisible") {
284 if (aux_val ==
"true") {
285 dau_invisible =
true;
286 }
else if (aux_val ==
"false") {
287 dau_invisible =
false;
289 }
else if (aux_type ==
"Visible") {
290 if (aux_val ==
"true") {
292 }
else if (aux_val ==
"false") {
295 }
else if (aux_type ==
"LineStyle") {
296 if (aux_val ==
"unbroken") {
297 line_style = G4VisAttributes::unbroken;
298 }
else if (aux_val ==
"dashed") {
299 line_style = G4VisAttributes::dashed;
300 }
else if (aux_val ==
"dotted") {
301 line_style = G4VisAttributes::dotted;
303 }
else if (aux_type ==
"LineWidth") {
304 line_width = atof(aux_val.c_str());
308 auto vis_attributes =
new G4VisAttributes();
309 vis_attributes->SetColor(rgba[0], rgba[1], rgba[2], rgba[3]);
310 vis_attributes->SetVisibility(visible);
311 vis_attributes->SetDaughtersInvisible(dau_invisible);
312 vis_attributes->SetForceWireframe(force_wireframe);
313 vis_attributes->SetForceSolid(force_solid);
314 vis_attributes->SetLineWidth(line_width);
315 vis_attributes->SetLineStyle(line_style);
323 const G4GDMLAuxListType* auxInfoList) {
324 int detector_version = atoi(auxValue.c_str());
326 std::string detector_name(
"");
327 std::string author(
"");
328 std::string description(
"");
330 for (
const auto& aux_info : *auxInfoList) {
331 G4String aux_type = aux_info.type;
332 G4String aux_val = aux_info.value;
334 if (aux_type ==
"DetectorName") {
335 detector_name = aux_val;
336 }
else if (aux_type ==
"Author") {
338 }
else if (aux_type ==
"Description") {
339 description = aux_val;
344 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.