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 ==
"ColorMode") {
58 }
else if (aux_type ==
"VisAttributes") {
60 }
else if (aux_type ==
"DetectorVersion") {
68 const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
69 std::vector<G4LogicalVolume*>::const_iterator lvciter;
70 for (lvciter = lvs->begin(); lvciter != lvs->end(); lvciter++) {
71 G4GDMLAuxListType aux_info_list =
72 parser_->GetVolumeAuxiliaryInformation(*lvciter);
74 for (
const auto& aux_info : aux_info_list) {
75 G4String aux_type = aux_info.type;
76 G4String aux_val = aux_info.value;
78 G4LogicalVolume* lv = (*lvciter);
80 if (aux_type ==
"MagneticField") {
81 const G4String& mag_field_name = aux_val;
82 G4MagneticField* mag_field =
84 if (mag_field !=
nullptr) {
85 auto mgr =
new G4FieldManager(mag_field);
94 "Unknown MagneticField ref in volume's auxiliary info: " +
95 std::string(mag_field_name.data()));
97 }
else if (aux_type ==
"Region") {
98 const G4String& region_name = aux_val;
99 G4Region* region = G4RegionStore::GetInstance()->GetRegion(region_name);
100 if (region !=
nullptr) {
101 region->AddRootLogicalVolume(lv);
105 EXCEPTION_RAISE(
"MissingInfo",
"Reference region '" +
106 std::string(region_name.data()) +
109 }
else if (aux_type ==
"VisAttributes") {
111 auto match = std::find(universal_visattributes_.begin(),
112 universal_visattributes_.end(), aux_val);
113 if (match == universal_visattributes_.end() &&
color_mode_ !=
"" &&
117 const G4String& vis_name = aux_val;
118 G4VisAttributes* vis_attributes =
120 if (vis_attributes !=
nullptr) {
121 lv->SetVisAttributes(vis_attributes);
125 EXCEPTION_RAISE(
"MissingInfo",
"Referenced VisAttributes '" +
126 std::string(vis_name.data()) +
135 const G4GDMLAuxListType* auxInfoList) {
137 G4String mag_field_type(
"");
138 for (
const auto& aux_info : *auxInfoList) {
139 G4String aux_type = aux_info.type;
140 G4String aux_val = aux_info.value;
142 if (aux_type ==
"MagneticFieldType") {
143 mag_field_type = aux_val;
148 if (mag_field_type ==
"") {
149 EXCEPTION_RAISE(
"MissingInfo",
150 "Missing MagFieldType for magnetic field definition.");
153 G4MagneticField* mag_field =
nullptr;
156 if (mag_field_type ==
"G4UniformMagField") {
159 for (
const auto& aux_info : *auxInfoList) {
160 G4String aux_type = aux_info.type;
161 G4String aux_val = aux_info.value;
162 G4String aux_unit = aux_info.unit;
164 G4String expr = aux_val +
"*" + aux_unit;
165 if (aux_type ==
"bx") {
166 bx =
eval_->Evaluate(expr);
167 }
else if (aux_type ==
"by") {
168 by =
eval_->Evaluate(expr);
169 }
else if (aux_type ==
"bz") {
170 bz =
eval_->Evaluate(expr);
173 G4ThreeVector field_components(bx, by, bz);
174 mag_field =
new G4UniformMagField(field_components);
180 }
else if (mag_field_type ==
"MagneticFieldMap3D") {
186 for (
const auto& aux_info : *auxInfoList) {
187 G4String aux_type = aux_info.type;
188 G4String aux_val = aux_info.value;
189 G4String aux_unit = aux_info.unit;
191 G4String expr = aux_val +
"*" + aux_unit;
193 if (aux_type ==
"File") {
195 }
else if (aux_type ==
"OffsetX") {
196 offset_x =
eval_->Evaluate(expr);
197 }
else if (aux_type ==
"OffsetY") {
198 offset_y =
eval_->Evaluate(expr);
199 }
else if (aux_type ==
"OffsetZ") {
200 offset_z =
eval_->Evaluate(expr);
204 if (file_name.size() == 0) {
205 EXCEPTION_RAISE(
"MissingInfo",
206 "File info with field data was not provided.");
214 G4FieldManager* field_mgr =
215 G4TransportationManager::GetTransportationManager()->GetFieldManager();
216 if (field_mgr->GetDetectorField() !=
nullptr) {
217 EXCEPTION_RAISE(
"MisAssign",
"Global mag field was already assigned.");
219 field_mgr->SetDetectorField(mag_field);
220 field_mgr->CreateChordFinder(mag_field);
223 EXCEPTION_RAISE(
"UnknownType",
"Unknown MagFieldType '" +
224 std::string(mag_field_type.data()) +
225 "' in auxiliary info.");
232 const G4GDMLAuxListType* auxInfoList) {
233 bool store_trajectories =
true;
234 for (
const auto& aux_info : *auxInfoList) {
235 G4String aux_type = aux_info.type;
236 G4String aux_val = aux_info.value;
238 if (aux_type ==
"StoreTrajectories") {
239 if (aux_val ==
"false") {
240 store_trajectories =
false;
241 }
else if (aux_val ==
"true") {
242 store_trajectories =
true;
246 G4VUserRegionInformation* region_info =
256 auto region =
new G4Region(name);
257 region->SetUserInformation(region_info);
259 region->SetProductionCuts(G4ProductionCutsTable::GetProductionCutsTable()
260 ->GetDefaultProductionCuts());
278 std::vector<std::string> valid_modes = {
"Region",
"Material"};
280 auto match = std::find(valid_modes.begin(), valid_modes.end(), mode);
282 if (match == valid_modes.end()) {
283 EXCEPTION_RAISE(
"InvalidMode",
"Color mode setting " + mode +
284 " doesn't match any available modes!");
292 const G4GDMLAuxListType* auxInfoList) {
293 std::array<G4double, 4> rgba = {1., 1., 1., 1.};
294 G4bool visible =
true;
295 G4bool dau_invisible =
false;
296 G4bool force_wireframe =
false;
297 G4bool force_solid =
false;
298 G4double line_width = 1.0;
299 G4VisAttributes::LineStyle line_style = G4VisAttributes::unbroken;
302 universal_visattributes_ = {
303 "InvisibleNoDau",
"InvisibleShowDau",
"NoDau",
"GrayWireFrame",
304 "BlueWireFrame",
"BlueSolid",
"Invisible",
"SpVis"};
305 auto match = std::find(universal_visattributes_.begin(),
306 universal_visattributes_.end(), name);
310 if (match == universal_visattributes_.end() &&
color_mode_ !=
"" &&
312 ldmx_log(debug) <<
"VisAttribute " << name
313 <<
" doesn't match current mode. Skipping...";
319 for (
const auto& aux_info : *auxInfoList) {
320 G4String aux_type = aux_info.type;
321 G4String aux_val = aux_info.value;
323 if (aux_type ==
"R") {
324 rgba[0] = atof(aux_val.c_str());
325 }
else if (aux_type ==
"G") {
326 rgba[1] = atof(aux_val.c_str());
327 }
else if (aux_type ==
"B") {
328 rgba[2] = atof(aux_val.c_str());
329 }
else if (aux_type ==
"A") {
330 rgba[3] = atof(aux_val.c_str());
331 }
else if (aux_type ==
"Style") {
332 if (aux_val ==
"wireframe") {
333 force_wireframe =
true;
334 }
else if (aux_val ==
"solid") {
337 }
else if (aux_type ==
"DaughtersInvisible") {
338 if (aux_val ==
"true") {
339 dau_invisible =
true;
340 }
else if (aux_val ==
"false") {
341 dau_invisible =
false;
343 }
else if (aux_type ==
"Visible") {
344 if (aux_val ==
"true") {
346 }
else if (aux_val ==
"false") {
349 }
else if (aux_type ==
"LineStyle") {
350 if (aux_val ==
"unbroken") {
351 line_style = G4VisAttributes::unbroken;
352 }
else if (aux_val ==
"dashed") {
353 line_style = G4VisAttributes::dashed;
354 }
else if (aux_val ==
"dotted") {
355 line_style = G4VisAttributes::dotted;
357 }
else if (aux_type ==
"LineWidth") {
358 line_width = atof(aux_val.c_str());
362 auto vis_attributes =
new G4VisAttributes();
363 vis_attributes->SetColor(rgba[0], rgba[1], rgba[2], rgba[3]);
364 vis_attributes->SetVisibility(visible);
365 vis_attributes->SetDaughtersInvisible(dau_invisible);
366 vis_attributes->SetForceWireframe(force_wireframe);
367 vis_attributes->SetForceSolid(force_solid);
368 vis_attributes->SetLineWidth(line_width);
369 vis_attributes->SetLineStyle(line_style);
377 const G4GDMLAuxListType* auxInfoList) {
378 int detector_version = atoi(auxValue.c_str());
380 std::string detector_name(
"");
381 std::string author(
"");
382 std::string description(
"");
384 for (
const auto& aux_info : *auxInfoList) {
385 G4String aux_type = aux_info.type;
386 G4String aux_val = aux_info.value;
388 if (aux_type ==
"DetectorName") {
389 detector_name = aux_val;
390 }
else if (aux_type ==
"Author") {
392 }
else if (aux_type ==
"Description") {
393 description = aux_val;
398 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.
std::string color_mode_
Color mode for visattributes.
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.
void selectColorMode(const G4String &mode)
Select the 'mode' for coloring in the visualization.