LDMX Software
Public Member Functions | Private Member Functions | Private Attributes | List of all members
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::DetectorHeaderdetectorHeader_ {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 30 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 28 of file AuxInfoReader.cxx.

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

32 {
33 delete eval_;
34 delete detectorHeader_;
35}
ldmx::DetectorHeader * detectorHeader_
Detector header with name and version.

References detectorHeader_, and eval_.

Member Function Documentation

◆ assignAuxInfoToVolumes()

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

Assign auxiliary info to volumes such as sensitive detectors.

Definition at line 61 of file AuxInfoReader.cxx.

61 {
62 const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
63 std::vector<G4LogicalVolume*>::const_iterator lvciter;
64 for (lvciter = lvs->begin(); lvciter != lvs->end(); lvciter++) {
65 G4GDMLAuxListType auxInfoList =
66 parser_->GetVolumeAuxiliaryInformation(*lvciter);
67
68 for (const auto& auxInfo : auxInfoList) {
69 G4String auxType = auxInfo.type;
70 G4String auxVal = auxInfo.value;
71
72 G4LogicalVolume* lv = (*lvciter);
73
74 if (auxType == "MagneticField") {
75 const G4String& magFieldName = auxVal;
76 G4MagneticField* magField =
78 if (magField != nullptr) {
79 auto mgr = new G4FieldManager(magField);
80 lv->SetFieldManager(
81 mgr,
82 true /* FIXME: hard-coded to force field manager to daughters */);
83 // G4cout << "Assigned magnetic field " << magFieldName << " to
84 // volume " << lv->GetName() << G4endl;
85 } else {
86 EXCEPTION_RAISE(
87 "MissingInfo",
88 "Unknown MagneticField ref in volume's auxiliary info: " +
89 std::string(magFieldName.data()));
90 }
91 } else if (auxType == "Region") {
92 const G4String& regionName = auxVal;
93 G4Region* region = G4RegionStore::GetInstance()->GetRegion(regionName);
94 if (region != nullptr) {
95 region->AddRootLogicalVolume(lv);
96 // G4cout << "Added volume " << lv->GetName() << " to region " <<
97 // regionName << G4endl;
98 } else {
99 EXCEPTION_RAISE("MissingInfo", "Reference region '" +
100 std::string(regionName.data()) +
101 "' was not found!");
102 }
103 } else if (auxType == "VisAttributes") {
104 const G4String& visName = auxVal;
105 G4VisAttributes* visAttributes =
107 if (visAttributes != nullptr) {
108 lv->SetVisAttributes(visAttributes);
109 // G4cout << "Assigned VisAttributes " << visName << " to volume "
110 // << lv->GetName() << G4endl;
111 } else {
112 EXCEPTION_RAISE("MissingInfo", "Referenced VisAttributes '" +
113 std::string(visName.data()) +
114 "' was not found!");
115 }
116 }
117 }
118 }
119}
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 315 of file AuxInfoReader.cxx.

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

References detectorHeader_.

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

122 {
123 // Find type of the mag field.
124 G4String magFieldType("");
125 for (const auto& auxInfo : *auxInfoList) {
126 G4String auxType = auxInfo.type;
127 G4String auxVal = auxInfo.value;
128
129 if (auxType == "MagneticFieldType") {
130 magFieldType = auxVal;
131 break;
132 }
133 }
134
135 if (magFieldType == "") {
136 EXCEPTION_RAISE("MissingInfo",
137 "Missing MagFieldType for magnetic field definition.");
138 }
139
140 G4MagneticField* magField = nullptr;
141
142 // Create a uniform mag field using the built-in Geant4 type.
143 if (magFieldType == "G4UniformMagField") {
144 double bx, by, bz;
145 bx = by = bz = 0.;
146 for (const auto& auxInfo : *auxInfoList) {
147 G4String auxType = auxInfo.type;
148 G4String auxVal = auxInfo.value;
149 G4String auxUnit = auxInfo.unit;
150
151 G4String expr = auxVal + "*" + auxUnit;
152 if (auxType == "bx") {
153 bx = eval_->Evaluate(expr);
154 } else if (auxType == "by") {
155 by = eval_->Evaluate(expr);
156 } else if (auxType == "bz") {
157 bz = eval_->Evaluate(expr);
158 }
159 }
160 G4ThreeVector fieldComponents(bx, by, bz);
161 magField = new G4UniformMagField(fieldComponents);
162
163 // G4cout << "Created G4UniformMagField " << magFieldName << " with field
164 // components " << fieldComponents << G4endl << G4endl;
165
166 // Create a global 3D field map by reading from a data file.
167 } else if (magFieldType == "MagneticFieldMap3D") {
168 string fileName;
169 double offsetX{};
170 double offsetY{};
171 double offsetZ{};
172
173 for (const auto& auxInfo : *auxInfoList) {
174 G4String auxType = auxInfo.type;
175 G4String auxVal = auxInfo.value;
176 G4String auxUnit = auxInfo.unit;
177
178 G4String expr = auxVal + "*" + auxUnit;
179
180 if (auxType == "File") {
181 fileName = auxVal;
182 } else if (auxType == "OffsetX") {
183 offsetX = eval_->Evaluate(expr);
184 } else if (auxType == "OffsetY") {
185 offsetY = eval_->Evaluate(expr);
186 } else if (auxType == "OffsetZ") {
187 offsetZ = eval_->Evaluate(expr);
188 }
189 }
190
191 if (fileName.size() == 0) {
192 EXCEPTION_RAISE("MissingInfo",
193 "File info with field data was not provided.");
194 }
195
196 // Create new 3D field map.
197 magField =
198 new MagneticFieldMap3D(fileName.c_str(), offsetX, offsetY, offsetZ);
199
200 // Assign field map as global field.
201 G4FieldManager* fieldMgr =
202 G4TransportationManager::GetTransportationManager()->GetFieldManager();
203 if (fieldMgr->GetDetectorField() != nullptr) {
204 EXCEPTION_RAISE("MisAssign", "Global mag field was already assigned.");
205 }
206 fieldMgr->SetDetectorField(magField);
207 fieldMgr->CreateChordFinder(magField);
208
209 } else {
210 EXCEPTION_RAISE("UnknownType", "Unknown MagFieldType '" +
211 std::string(magFieldType.data()) +
212 "' in auxiliary info.");
213 }
214
215 MagneticFieldStore::getInstance()->addMagneticField(magFieldName, magField);
216}
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 218 of file AuxInfoReader.cxx.

219 {
220 bool storeTrajectories = true;
221 for (const auto& auxInfo : *auxInfoList) {
222 G4String auxType = auxInfo.type;
223 G4String auxVal = auxInfo.value;
224
225 if (auxType == "StoreTrajectories") {
226 if (auxVal == "false") {
227 storeTrajectories = false;
228 } else if (auxVal == "true") {
229 storeTrajectories = true;
230 }
231 }
232 }
233 G4VUserRegionInformation* regionInfo =
234 new UserRegionInformation(storeTrajectories);
235 // This looks like a memory leak, but isn't. I (Einar) have checked. Geant4
236 // registers the region in the constructor and deletes it at the end.
237 //
238 // Some static analysis tools may struggle with identifying that this one
239 // happens to be fine. The NOLINT comment tells clang-tidy to not bother
240 // within the region
241 //
242 // NOLINTBEGIN
243 auto region = new G4Region(name);
244 region->SetUserInformation(regionInfo);
245}

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

249 {
250 std::array<G4double, 4> rgba = {1., 1., 1., 1.};
251 G4bool visible = true;
252 G4bool dauInvisible = false;
253 G4bool forceWireframe = false;
254 G4bool forceSolid = false;
255 G4double lineWidth = 1.0;
256 G4VisAttributes::LineStyle lineStyle = G4VisAttributes::unbroken;
257
258 for (const auto& auxInfo : *auxInfoList) {
259 G4String auxType = auxInfo.type;
260 G4String auxVal = auxInfo.value;
261
262 if (auxType == "R") {
263 rgba[0] = atof(auxVal.c_str());
264 } else if (auxType == "G") {
265 rgba[1] = atof(auxVal.c_str());
266 } else if (auxType == "B") {
267 rgba[2] = atof(auxVal.c_str());
268 } else if (auxType == "A") {
269 rgba[3] = atof(auxVal.c_str());
270 } else if (auxType == "Style") {
271 if (auxVal == "wireframe") {
272 forceWireframe = true;
273 } else if (auxVal == "solid") {
274 forceSolid = true;
275 }
276 } else if (auxType == "DaughtersInvisible") {
277 if (auxVal == "true") {
278 dauInvisible = true;
279 } else if (auxVal == "false") {
280 dauInvisible = false;
281 }
282 } else if (auxType == "Visible") {
283 if (auxVal == "true") {
284 visible = true;
285 } else if (auxVal == "false") {
286 visible = false;
287 }
288 } else if (auxType == "LineStyle") {
289 if (auxVal == "unbroken") {
290 lineStyle = G4VisAttributes::unbroken;
291 } else if (auxVal == "dashed") {
292 lineStyle = G4VisAttributes::dashed;
293 } else if (auxVal == "dotted") {
294 lineStyle = G4VisAttributes::dotted;
295 }
296 } else if (auxType == "LineWidth") {
297 lineWidth = atof(auxVal.c_str());
298 }
299 }
300
301 auto visAttributes = new G4VisAttributes();
302 visAttributes->SetColor(rgba[0], rgba[1], rgba[2], rgba[3]);
303 visAttributes->SetVisibility(visible);
304 visAttributes->SetDaughtersInvisible(dauInvisible);
305 visAttributes->SetForceWireframe(forceWireframe);
306 visAttributes->SetForceSolid(forceSolid);
307 visAttributes->SetLineWidth(lineWidth);
308 visAttributes->SetLineStyle(lineStyle);
310
311 // G4cout << "Created VisAttributes " << name << G4endl << (*visAttributes) <<
312 // G4endl << G4endl;
313}
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 58 of file AuxInfoReader.h.

58{ return detectorHeader_; }

References detectorHeader_.

◆ readGlobalAuxInfo()

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

Read the global auxiliary information from the auxinfo block.

Definition at line 37 of file AuxInfoReader.cxx.

37 {
38 const G4GDMLAuxListType* auxInfoList = parser_->GetAuxList();
39 for (const auto& auxInfo : *auxInfoList) {
40 G4String auxType = auxInfo.type;
41 G4String auxVal = auxInfo.value;
42
43 if (auxType == "SensDet") {
44 std::cerr
45 << "[ WARN ] : Not defining SensDet in GDML since v1.0 of SimCore. "
46 "See https://github.com/LDMX-Software/SimCore/issues/39"
47 << std::endl;
48 } else if (auxType == "MagneticField") {
49 createMagneticField(auxVal, auxInfo.auxList);
50 } else if (auxType == "Region") {
51 createRegion(auxVal, auxInfo.auxList);
52 } else if (auxType == "VisAttributes") {
53 createVisAttributes(auxVal, auxInfo.auxList);
54 } else if (auxType == "DetectorVersion") {
55 createDetectorHeader(auxVal, auxInfo.auxList);
56 }
57 }
58 return;
59}
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

◆ detectorHeader_

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

Detector header with name and version.

Definition at line 106 of file AuxInfoReader.h.

106{nullptr};

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

◆ eval_

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

The GDML expression evaluator.

Definition at line 101 of file AuxInfoReader.h.

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

◆ parser_

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

The GDML parser.

Definition at line 96 of file AuxInfoReader.h.

Referenced by assignAuxInfoToVolumes(), and readGlobalAuxInfo().


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