LDMX Software
simcore::geo::AuxInfoReader Class Reference

Reads auxiliary information from GDML userinfo block. More...

#include <AuxInfoReader.h>

Public Member Functions

 AuxInfoReader (G4GDMLParser *parser, const framework::config::Parameters &ps)
 Class constructor.
 
virtual ~AuxInfoReader ()
 Class destructor.
 
void readGlobalAuxInfo ()
 Read the global auxiliary information from the auxinfo block.
 
void assignAuxInfoToVolumes ()
 Assign auxiliary info to volumes such as sensitive detectors.
 
ldmx::DetectorHeadergetDetectorHeader ()
 Get the detector header that was created from the userinfo block.
 

Private Member Functions

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 createVisAttributes (const G4String &name, const G4GDMLAuxListType *auxInfoList)
 Create visualization attributes from GDML data.
 
void createDetectorHeader (const G4String &detectorVersion, const G4GDMLAuxListType *auxInfoList)
 Create the detector header from the global auxinfo.
 

Private Attributes

G4GDMLParser * parser_
 The GDML parser.
 
G4GDMLEvaluator * eval_
 The GDML expression evaluator.
 
ldmx::DetectorHeaderdetector_header_ {nullptr}
 Detector header with name and version.
 

Detailed Description

Reads auxiliary information from GDML userinfo block.

Note
This class reads information to define a detector header block, sensitive detectors, visualization attributes, magnetic fields, detector IDs, and detector regions from the userinfo block of a GDML file. These objects are then assigned to the appropriate logical volumes which have auxiliary tags that reference these objects by name.

Definition at line 27 of file AuxInfoReader.h.

Constructor & Destructor Documentation

◆ AuxInfoReader()

simcore::geo::AuxInfoReader::AuxInfoReader ( G4GDMLParser * parser,
const framework::config::Parameters & ps )

Class constructor.

Parameters
parserThe GDML parser.
psconfiguration parameters

Definition at line 30 of file AuxInfoReader.cxx.

32 : parser_(theParser), eval_(new G4GDMLEvaluator) {}
G4GDMLEvaluator * eval_
The GDML expression evaluator.
G4GDMLParser * parser_
The GDML parser.

◆ ~AuxInfoReader()

simcore::geo::AuxInfoReader::~AuxInfoReader ( )
virtual

Class destructor.

Definition at line 34 of file AuxInfoReader.cxx.

34 {
35 delete eval_;
36 delete detector_header_;
37}
ldmx::DetectorHeader * detector_header_
Detector header with name and version.

References detector_header_, and eval_.

Member Function Documentation

◆ assignAuxInfoToVolumes()

void simcore::geo::AuxInfoReader::assignAuxInfoToVolumes ( )

Assign auxiliary info to volumes such as sensitive detectors.

Definition at line 63 of file AuxInfoReader.cxx.

63 {
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);
69
70 for (const auto& aux_info : aux_info_list) {
71 G4String aux_type = aux_info.type;
72 G4String aux_val = aux_info.value;
73
74 G4LogicalVolume* lv = (*lvciter);
75
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);
82 lv->SetFieldManager(
83 mgr,
84 true /* FIXME: hard-coded to force field manager to daughters */);
85 // G4cout << "Assigned magnetic field " << magFieldName << " to
86 // volume " << lv->GetName() << G4endl;
87 } else {
88 EXCEPTION_RAISE(
89 "MissingInfo",
90 "Unknown MagneticField ref in volume's auxiliary info: " +
91 std::string(mag_field_name.data()));
92 }
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);
98 // G4cout << "Added volume " << lv->GetName() << " to region " <<
99 // regionName << G4endl;
100 } else {
101 EXCEPTION_RAISE("MissingInfo", "Reference region '" +
102 std::string(region_name.data()) +
103 "' was not found!");
104 }
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);
111 // G4cout << "Assigned VisAttributes " << visName << " to volume "
112 // << lv->GetName() << G4endl;
113 } else {
114 EXCEPTION_RAISE("MissingInfo", "Referenced VisAttributes '" +
115 std::string(vis_name.data()) +
116 "' was not found!");
117 }
118 }
119 }
120 }
121}
static MagneticFieldStore * getInstance()
Get the global instance of the magnetic field store.
G4MagneticField * getMagneticField(const std::string &name)
Get a magnetic field by name.
G4VisAttributes * getVisAttributes(const std::string &name)
Get vis attributes by name.
static VisAttributesStore * getInstance()
Get the global instance of the store.

References simcore::MagneticFieldStore::getInstance(), simcore::VisAttributesStore::getInstance(), simcore::MagneticFieldStore::getMagneticField(), simcore::VisAttributesStore::getVisAttributes(), and parser_.

◆ createDetectorHeader()

void simcore::geo::AuxInfoReader::createDetectorHeader ( const G4String & detectorVersion,
const G4GDMLAuxListType * auxInfoList )
private

Create the detector header from the global auxinfo.

Parameters
detectorVersionThe aux value with the detector version.
auxInfoListThe aux info with the detector header information.

Definition at line 317 of file AuxInfoReader.cxx.

318 {
319 int detector_version = atoi(auxValue.c_str());
320
321 std::string detector_name("");
322 std::string author("");
323 std::string description("");
324
325 for (const auto& aux_info : *auxInfoList) {
326 G4String aux_type = aux_info.type;
327 G4String aux_val = aux_info.value;
328
329 if (aux_type == "DetectorName") {
330 detector_name = aux_val;
331 } else if (aux_type == "Author") {
332 author = aux_val;
333 } else if (aux_type == "Description") {
334 description = aux_val;
335 }
336 }
337
338 detector_header_ = new ldmx::DetectorHeader(detector_name, detector_version,
339 description, author);
340
341 /*G4cout << G4endl;
342 G4cout << "Read detector header from userinfo: " << G4endl;
343 G4cout << " DetectorName: " << detector_header_->getName() << G4endl;
344 G4cout << " DetectorVersion: " << detector_header_->getVersion() << G4endl;
345 G4cout << " Author: " << detector_header_->getAuthor() << G4endl;
346 G4cout << " Description: " << detector_header_->getDescription() << G4endl;
347 G4cout << G4endl;*/
348}
Defines detector header information.

References detector_header_.

Referenced by readGlobalAuxInfo().

◆ createMagneticField()

void simcore::geo::AuxInfoReader::createMagneticField ( const G4String & name,
const G4GDMLAuxListType * auxInfoList )
private

Create a magnetic field from GDML data.

Parameters
nameThe name of the magnetic field.
auxInfoListThe aux info defining the magnetic field.

Definition at line 123 of file AuxInfoReader.cxx.

124 {
125 // Find type of the mag field.
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;
130
131 if (aux_type == "MagneticFieldType") {
132 mag_field_type = aux_val;
133 break;
134 }
135 }
136
137 if (mag_field_type == "") {
138 EXCEPTION_RAISE("MissingInfo",
139 "Missing MagFieldType for magnetic field definition.");
140 }
141
142 G4MagneticField* mag_field = nullptr;
143
144 // Create a uniform mag field using the built-in Geant4 type.
145 if (mag_field_type == "G4UniformMagField") {
146 double bx, by, bz;
147 bx = by = bz = 0.;
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;
152
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);
160 }
161 }
162 G4ThreeVector field_components(bx, by, bz);
163 mag_field = new G4UniformMagField(field_components);
164
165 // G4cout << "Created G4UniformMagField " << magFieldName << " with field
166 // components " << fieldComponents << G4endl << G4endl;
167
168 // Create a global 3D field map by reading from a data file.
169 } else if (mag_field_type == "MagneticFieldMap3D") {
170 string file_name;
171 double offset_x{};
172 double offset_y{};
173 double offset_z{};
174
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;
179
180 G4String expr = aux_val + "*" + aux_unit;
181
182 if (aux_type == "File") {
183 file_name = aux_val;
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);
190 }
191 }
192
193 if (file_name.size() == 0) {
194 EXCEPTION_RAISE("MissingInfo",
195 "File info with field data was not provided.");
196 }
197
198 // Create new 3D field map.
199 mag_field =
200 new MagneticFieldMap3D(file_name.c_str(), offset_x, offset_y, offset_z);
201
202 // Assign field map as global field.
203 G4FieldManager* field_mgr =
204 G4TransportationManager::GetTransportationManager()->GetFieldManager();
205 if (field_mgr->GetDetectorField() != nullptr) {
206 EXCEPTION_RAISE("MisAssign", "Global mag field was already assigned.");
207 }
208 field_mgr->SetDetectorField(mag_field);
209 field_mgr->CreateChordFinder(mag_field);
210
211 } else {
212 EXCEPTION_RAISE("UnknownType", "Unknown MagFieldType '" +
213 std::string(mag_field_type.data()) +
214 "' in auxiliary info.");
215 }
216
217 MagneticFieldStore::getInstance()->addMagneticField(magFieldName, mag_field);
218}
void addMagneticField(const std::string &name, G4MagneticField *magField)
Add a magnetic field by name.

References simcore::MagneticFieldStore::addMagneticField(), eval_, and simcore::MagneticFieldStore::getInstance().

Referenced by readGlobalAuxInfo().

◆ createRegion()

void simcore::geo::AuxInfoReader::createRegion ( const G4String & name,
const G4GDMLAuxListType * auxInfoList )
private

Create a detector region from GDML data.

Parameters
nameThe name of the detector region.
auxInfoListThe aux info defining the detector region.

Definition at line 220 of file AuxInfoReader.cxx.

221 {
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;
226
227 if (aux_type == "StoreTrajectories") {
228 if (aux_val == "false") {
229 store_trajectories = false;
230 } else if (aux_val == "true") {
231 store_trajectories = true;
232 }
233 }
234 }
235 G4VUserRegionInformation* region_info =
236 new UserRegionInformation(store_trajectories);
237 // This looks like a memory leak, but isn't. I (Einar) have checked. Geant4
238 // registers the region in the constructor and deletes it at the end.
239 //
240 // Some static analysis tools may struggle with identifying that this one
241 // happens to be fine. The NOLINT comment tells clang-tidy to not bother
242 // within the region
243 //
244 // NOLINTBEGIN
245 auto region = new G4Region(name);
246 region->SetUserInformation(region_info);
247}

Referenced by readGlobalAuxInfo().

◆ createVisAttributes()

void simcore::geo::AuxInfoReader::createVisAttributes ( const G4String & name,
const G4GDMLAuxListType * auxInfoList )
private

Create visualization attributes from GDML data.

Parameters
nameThe name of the visualization attributes.
auxInfoListThe aux info defining the visualization attributes.

Definition at line 250 of file AuxInfoReader.cxx.

251 {
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;
259
260 for (const auto& aux_info : *auxInfoList) {
261 G4String aux_type = aux_info.type;
262 G4String aux_val = aux_info.value;
263
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") {
276 force_solid = true;
277 }
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;
283 }
284 } else if (aux_type == "Visible") {
285 if (aux_val == "true") {
286 visible = true;
287 } else if (aux_val == "false") {
288 visible = false;
289 }
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;
297 }
298 } else if (aux_type == "LineWidth") {
299 line_width = atof(aux_val.c_str());
300 }
301 }
302
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);
311 VisAttributesStore::getInstance()->addVisAttributes(name, vis_attributes);
312
313 // G4cout << "Created VisAttributes " << name << G4endl << (*visAttributes) <<
314 // G4endl << G4endl;
315}
void addVisAttributes(const std::string &name, G4VisAttributes *visAttributes)
Register a vis attributes by name.

References simcore::VisAttributesStore::addVisAttributes(), and simcore::VisAttributesStore::getInstance().

Referenced by readGlobalAuxInfo().

◆ getDetectorHeader()

ldmx::DetectorHeader * simcore::geo::AuxInfoReader::getDetectorHeader ( )
inline

Get the detector header that was created from the userinfo block.

Returns
The detector header.

Definition at line 55 of file AuxInfoReader.h.

55{ return detector_header_; }

References detector_header_.

◆ readGlobalAuxInfo()

void simcore::geo::AuxInfoReader::readGlobalAuxInfo ( )

Read the global auxiliary information from the auxinfo block.

Definition at line 39 of file AuxInfoReader.cxx.

39 {
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;
44
45 if (aux_type == "SensDet") {
46 std::cerr
47 << "[ WARN ] : Not defining SensDet in GDML since v1.0 of SimCore. "
48 "See https://github.com/LDMX-Software/SimCore/issues/39"
49 << std::endl;
50 } else if (aux_type == "MagneticField") {
51 createMagneticField(aux_val, aux_info.auxList);
52 } else if (aux_type == "Region") {
53 createRegion(aux_val, aux_info.auxList);
54 } else if (aux_type == "VisAttributes") {
55 createVisAttributes(aux_val, aux_info.auxList);
56 } else if (aux_type == "DetectorVersion") {
57 createDetectorHeader(aux_val, aux_info.auxList);
58 }
59 }
60 return;
61}
void createDetectorHeader(const G4String &detectorVersion, const G4GDMLAuxListType *auxInfoList)
Create the detector header from the global auxinfo.
void createVisAttributes(const G4String &name, const G4GDMLAuxListType *auxInfoList)
Create visualization attributes from GDML data.
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.

References createDetectorHeader(), createMagneticField(), createRegion(), createVisAttributes(), and parser_.

Member Data Documentation

◆ detector_header_

ldmx::DetectorHeader* simcore::geo::AuxInfoReader::detector_header_ {nullptr}
private

Detector header with name and version.

Definition at line 103 of file AuxInfoReader.h.

103{nullptr};

Referenced by createDetectorHeader(), getDetectorHeader(), and ~AuxInfoReader().

◆ eval_

G4GDMLEvaluator* simcore::geo::AuxInfoReader::eval_
private

The GDML expression evaluator.

Definition at line 98 of file AuxInfoReader.h.

Referenced by createMagneticField(), and ~AuxInfoReader().

◆ parser_

G4GDMLParser* simcore::geo::AuxInfoReader::parser_
private

The GDML parser.

Definition at line 93 of file AuxInfoReader.h.

Referenced by assignAuxInfoToVolumes(), and readGlobalAuxInfo().


The documentation for this class was generated from the following files: