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 "G4ProductionCutsTable.hh"
18#include "G4RegionStore.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 ==
"ColorMode") {
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") {
109 auto match = std::find(universal_visattributes_.begin(),
110 universal_visattributes_.end(), aux_val);
111 if (match == universal_visattributes_.end() &&
color_mode_ !=
"" &&
115 const G4String& vis_name = aux_val;
116 G4VisAttributes* vis_attributes =
118 if (vis_attributes !=
nullptr) {
119 lv->SetVisAttributes(vis_attributes);
123 EXCEPTION_RAISE(
"MissingInfo",
"Referenced VisAttributes '" +
124 std::string(vis_name.data()) +
133 const G4GDMLAuxListType* auxInfoList) {
135 G4String mag_field_type(
"");
136 for (
const auto& aux_info : *auxInfoList) {
137 G4String aux_type = aux_info.type;
138 G4String aux_val = aux_info.value;
140 if (aux_type ==
"MagneticFieldType") {
141 mag_field_type = aux_val;
146 if (mag_field_type ==
"") {
147 EXCEPTION_RAISE(
"MissingInfo",
148 "Missing MagFieldType for magnetic field definition.");
151 G4MagneticField* mag_field =
nullptr;
154 if (mag_field_type ==
"G4UniformMagField") {
157 for (
const auto& aux_info : *auxInfoList) {
158 G4String aux_type = aux_info.type;
159 G4String aux_val = aux_info.value;
160 G4String aux_unit = aux_info.unit;
162 G4String expr = aux_val +
"*" + aux_unit;
163 if (aux_type ==
"bx") {
164 bx =
eval_->Evaluate(expr);
165 }
else if (aux_type ==
"by") {
166 by =
eval_->Evaluate(expr);
167 }
else if (aux_type ==
"bz") {
168 bz =
eval_->Evaluate(expr);
171 G4ThreeVector field_components(bx, by, bz);
172 mag_field =
new G4UniformMagField(field_components);
178 }
else if (mag_field_type ==
"MagneticFieldMap3D") {
184 for (
const auto& aux_info : *auxInfoList) {
185 G4String aux_type = aux_info.type;
186 G4String aux_val = aux_info.value;
187 G4String aux_unit = aux_info.unit;
189 G4String expr = aux_val +
"*" + aux_unit;
191 if (aux_type ==
"File") {
193 }
else if (aux_type ==
"OffsetX") {
194 offset_x =
eval_->Evaluate(expr);
195 }
else if (aux_type ==
"OffsetY") {
196 offset_y =
eval_->Evaluate(expr);
197 }
else if (aux_type ==
"OffsetZ") {
198 offset_z =
eval_->Evaluate(expr);
202 if (file_name.size() == 0) {
203 EXCEPTION_RAISE(
"MissingInfo",
204 "File info with field data was not provided.");
212 G4FieldManager* field_mgr =
213 G4TransportationManager::GetTransportationManager()->GetFieldManager();
214 if (field_mgr->GetDetectorField() !=
nullptr) {
215 EXCEPTION_RAISE(
"MisAssign",
"Global mag field was already assigned.");
217 field_mgr->SetDetectorField(mag_field);
218 field_mgr->CreateChordFinder(mag_field);
221 EXCEPTION_RAISE(
"UnknownType",
"Unknown MagFieldType '" +
222 std::string(mag_field_type.data()) +
223 "' in auxiliary info.");
230 const G4GDMLAuxListType* auxInfoList) {
231 bool store_trajectories =
true;
232 for (
const auto& aux_info : *auxInfoList) {
233 G4String aux_type = aux_info.type;
234 G4String aux_val = aux_info.value;
236 if (aux_type ==
"StoreTrajectories") {
237 if (aux_val ==
"false") {
238 store_trajectories =
false;
239 }
else if (aux_val ==
"true") {
240 store_trajectories =
true;
244 G4VUserRegionInformation* region_info =
254 auto region =
new G4Region(name);
255 region->SetUserInformation(region_info);
257 region->SetProductionCuts(G4ProductionCutsTable::GetProductionCutsTable()
258 ->GetDefaultProductionCuts());
276 std::vector<std::string> valid_modes = {
"Region",
"Material"};
278 auto match = std::find(valid_modes.begin(), valid_modes.end(), mode);
280 if (match == valid_modes.end()) {
281 EXCEPTION_RAISE(
"InvalidMode",
"Color mode setting " + mode +
282 " doesn't match any available modes!");
290 const G4GDMLAuxListType* auxInfoList) {
291 std::array<G4double, 4> rgba = {1., 1., 1., 1.};
292 G4bool visible =
true;
293 G4bool dau_invisible =
false;
294 G4bool force_wireframe =
false;
295 G4bool force_solid =
false;
296 G4double line_width = 1.0;
297 G4VisAttributes::LineStyle line_style = G4VisAttributes::unbroken;
300 universal_visattributes_ = {
301 "InvisibleNoDau",
"InvisibleShowDau",
"NoDau",
"GrayWireFrame",
302 "BlueWireFrame",
"BlueSolid",
"Invisible",
"SpVis"};
303 auto match = std::find(universal_visattributes_.begin(),
304 universal_visattributes_.end(), name);
308 if (match == universal_visattributes_.end() &&
color_mode_ !=
"" &&
310 ldmx_log(debug) <<
"VisAttribute " << name
311 <<
" doesn't match current mode. Skipping...";
317 for (
const auto& aux_info : *auxInfoList) {
318 G4String aux_type = aux_info.type;
319 G4String aux_val = aux_info.value;
321 if (aux_type ==
"R") {
322 rgba[0] = atof(aux_val.c_str());
323 }
else if (aux_type ==
"G") {
324 rgba[1] = atof(aux_val.c_str());
325 }
else if (aux_type ==
"B") {
326 rgba[2] = atof(aux_val.c_str());
327 }
else if (aux_type ==
"A") {
328 rgba[3] = atof(aux_val.c_str());
329 }
else if (aux_type ==
"Style") {
330 if (aux_val ==
"wireframe") {
331 force_wireframe =
true;
332 }
else if (aux_val ==
"solid") {
335 }
else if (aux_type ==
"DaughtersInvisible") {
336 if (aux_val ==
"true") {
337 dau_invisible =
true;
338 }
else if (aux_val ==
"false") {
339 dau_invisible =
false;
341 }
else if (aux_type ==
"Visible") {
342 if (aux_val ==
"true") {
344 }
else if (aux_val ==
"false") {
347 }
else if (aux_type ==
"LineStyle") {
348 if (aux_val ==
"unbroken") {
349 line_style = G4VisAttributes::unbroken;
350 }
else if (aux_val ==
"dashed") {
351 line_style = G4VisAttributes::dashed;
352 }
else if (aux_val ==
"dotted") {
353 line_style = G4VisAttributes::dotted;
355 }
else if (aux_type ==
"LineWidth") {
356 line_width = atof(aux_val.c_str());
360 auto vis_attributes =
new G4VisAttributes();
361 vis_attributes->SetColor(rgba[0], rgba[1], rgba[2], rgba[3]);
362 vis_attributes->SetVisibility(visible);
363 vis_attributes->SetDaughtersInvisible(dau_invisible);
364 vis_attributes->SetForceWireframe(force_wireframe);
365 vis_attributes->SetForceSolid(force_solid);
366 vis_attributes->SetLineWidth(line_width);
367 vis_attributes->SetLineStyle(line_style);
375 const G4GDMLAuxListType* auxInfoList) {
376 int detector_version = atoi(auxValue.c_str());
378 std::string detector_name(
"");
379 std::string author(
"");
380 std::string description(
"");
382 for (
const auto& aux_info : *auxInfoList) {
383 G4String aux_type = aux_info.type;
384 G4String aux_val = aux_info.value;
386 if (aux_type ==
"DetectorName") {
387 detector_name = aux_val;
388 }
else if (aux_type ==
"Author") {
390 }
else if (aux_type ==
"Description") {
391 description = aux_val;
396 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.