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 32 of file AuxInfoReader.cxx.

34 : 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 36 of file AuxInfoReader.cxx.

36 {
37 delete eval_;
38 delete detector_header_;
39}
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 65 of file AuxInfoReader.cxx.

65 {
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);
71
72 for (const auto& aux_info : aux_info_list) {
73 G4String aux_type = aux_info.type;
74 G4String aux_val = aux_info.value;
75
76 G4LogicalVolume* lv = (*lvciter);
77
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);
84 lv->SetFieldManager(
85 mgr,
86 true /* FIXME: hard-coded to force field manager to daughters */);
87 // G4cout << "Assigned magnetic field " << magFieldName << " to
88 // volume " << lv->GetName() << G4endl;
89 } else {
90 EXCEPTION_RAISE(
91 "MissingInfo",
92 "Unknown MagneticField ref in volume's auxiliary info: " +
93 std::string(mag_field_name.data()));
94 }
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);
100 // G4cout << "Added volume " << lv->GetName() << " to region " <<
101 // regionName << G4endl;
102 } else {
103 EXCEPTION_RAISE("MissingInfo", "Reference region '" +
104 std::string(region_name.data()) +
105 "' was not found!");
106 }
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);
113 // G4cout << "Assigned VisAttributes " << visName << " to volume "
114 // << lv->GetName() << G4endl;
115 } else {
116 EXCEPTION_RAISE("MissingInfo", "Referenced VisAttributes '" +
117 std::string(vis_name.data()) +
118 "' was not found!");
119 }
120 }
121 }
122 }
123}
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 322 of file AuxInfoReader.cxx.

323 {
324 int detector_version = atoi(auxValue.c_str());
325
326 std::string detector_name("");
327 std::string author("");
328 std::string description("");
329
330 for (const auto& aux_info : *auxInfoList) {
331 G4String aux_type = aux_info.type;
332 G4String aux_val = aux_info.value;
333
334 if (aux_type == "DetectorName") {
335 detector_name = aux_val;
336 } else if (aux_type == "Author") {
337 author = aux_val;
338 } else if (aux_type == "Description") {
339 description = aux_val;
340 }
341 }
342
343 detector_header_ = new ldmx::DetectorHeader(detector_name, detector_version,
344 description, author);
345
346 /*G4cout << G4endl;
347 G4cout << "Read detector header from userinfo: " << G4endl;
348 G4cout << " DetectorName: " << detector_header_->getName() << G4endl;
349 G4cout << " DetectorVersion: " << detector_header_->getVersion() << G4endl;
350 G4cout << " Author: " << detector_header_->getAuthor() << G4endl;
351 G4cout << " Description: " << detector_header_->getDescription() << G4endl;
352 G4cout << G4endl;*/
353}
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 125 of file AuxInfoReader.cxx.

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

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

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 255 of file AuxInfoReader.cxx.

256 {
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;
264
265 for (const auto& aux_info : *auxInfoList) {
266 G4String aux_type = aux_info.type;
267 G4String aux_val = aux_info.value;
268
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") {
281 force_solid = true;
282 }
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;
288 }
289 } else if (aux_type == "Visible") {
290 if (aux_val == "true") {
291 visible = true;
292 } else if (aux_val == "false") {
293 visible = false;
294 }
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;
302 }
303 } else if (aux_type == "LineWidth") {
304 line_width = atof(aux_val.c_str());
305 }
306 }
307
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);
316 VisAttributesStore::getInstance()->addVisAttributes(name, vis_attributes);
317
318 // G4cout << "Created VisAttributes " << name << G4endl << (*visAttributes) <<
319 // G4endl << G4endl;
320}
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 41 of file AuxInfoReader.cxx.

41 {
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;
46
47 if (aux_type == "SensDet") {
48 std::cerr
49 << "[ WARN ] : Not defining SensDet in GDML since v1.0 of SimCore. "
50 "See https://github.com/LDMX-Software/SimCore/issues/39"
51 << std::endl;
52 } else if (aux_type == "MagneticField") {
53 createMagneticField(aux_val, aux_info.auxList);
54 } else if (aux_type == "Region") {
55 createRegion(aux_val, aux_info.auxList);
56 } else if (aux_type == "VisAttributes") {
57 createVisAttributes(aux_val, aux_info.auxList);
58 } else if (aux_type == "DetectorVersion") {
59 createDetectorHeader(aux_val, aux_info.auxList);
60 }
61 }
62 return;
63}
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: