Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4GDMLRead.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// G4GDMLRead implementation
27//
28// Author: Zoltan Torzsok, November 2007
29// --------------------------------------------------------------------
30
31#include "globals.hh"
32
33#include "G4GDMLRead.hh"
34
35#include "G4UnitsTable.hh"
36#include "G4Element.hh"
37#include "G4Material.hh"
38#include "G4SolidStore.hh"
41#include "G4EnvironmentUtils.hh"
42#include "G4Exception.hh"
43
44// --------------------------------------------------------------------
46{
47 // Make sure units are defined.
49}
50
51// --------------------------------------------------------------------
55
56// --------------------------------------------------------------------
57G4String G4GDMLRead::Transcode(const XMLCh* const toTranscode)
58{
59 char* char_str = xercesc::XMLString::transcode(toTranscode);
60 G4String my_str(char_str);
61 xercesc::XMLString::release(&char_str);
62 return my_str;
63}
64
65// --------------------------------------------------------------------
67{
68 check = flag;
69}
70
71// --------------------------------------------------------------------
73{
74 G4String nameOut(nameIn);
75
76 if(inLoop > 0)
77 {
78 nameOut = eval.SolveBrackets(nameOut);
79 }
80 if(strip)
81 {
82 StripName(nameOut);
83 }
84
85 return nameOut;
86}
87
88// --------------------------------------------------------------------
90 G4VPhysicalVolume* physvol)
91{
92 G4String nameOut(nameIn);
93
94 if(nameIn.empty())
95 {
96 std::stringstream stream;
97 stream << physvol->GetLogicalVolume()->GetName() << "_PV";
98 nameOut = stream.str();
99 }
100 nameOut = eval.SolveBrackets(nameOut);
101
102 physvol->SetName(nameOut);
103}
104
105// --------------------------------------------------------------------
107{
108 G4String sname(name);
109 StripName(sname);
110 return sname;
111}
112
113// --------------------------------------------------------------------
115{
116 auto idx = name.find("0x");
117 if(idx != G4String::npos)
118 {
119 name.erase(idx);
120 }
121}
122
123// --------------------------------------------------------------------
125{
126 // Strips off names of volumes, solids elements and materials from possible
127 // reference pointers or IDs attached to their original identifiers.
128
132 const G4ElementTable* elements = G4Element::GetElementTable();
134
135 G4cout << "Stripping off GDML names of materials, solids and volumes ..."
136 << G4endl;
137
138 G4String sname;
139 std::size_t i;
140
141 // Solids...
142 //
143 for(i = 0; i < solids->size(); ++i)
144 {
145 G4VSolid* psol = (*solids)[i];
146 sname = psol->GetName();
147 StripName(sname);
148 psol->SetName(sname);
149 }
150 solids->UpdateMap();
151
152 // Logical volumes...
153 //
154 for(i = 0; i < lvols->size(); ++i)
155 {
156 G4LogicalVolume* lvol = (*lvols)[i];
157 sname = lvol->GetName();
158 StripName(sname);
159 lvol->SetName(sname);
160 }
161 lvols->UpdateMap();
162
163 // Physical volumes...
164 //
165 for(i = 0; i < pvols->size(); ++i)
166 {
167 G4VPhysicalVolume* pvol = (*pvols)[i];
168 sname = pvol->GetName();
169 StripName(sname);
170 pvol->SetName(sname);
171 }
172 pvols->UpdateMap();
173
174 // Materials...
175 //
176 for(i = 0; i < materials->size(); ++i)
177 {
178 G4Material* pmat = (*materials)[i];
179 sname = pmat->GetName();
180 StripName(sname);
181 pmat->SetName(sname);
182 }
183
184 // Elements...
185 //
186 for(i = 0; i < elements->size(); ++i)
187 {
188 G4Element* pelm = (*elements)[i];
189 sname = pelm->GetName();
190 StripName(sname);
191 pelm->SetName(sname);
192 }
193}
194
195// --------------------------------------------------------------------
196void G4GDMLRead::LoopRead( const xercesc::DOMElement* const element,
197 void (G4GDMLRead::*func)(const xercesc::DOMElement* const))
198{
199 G4String var;
200 G4String from;
201 G4String to;
202 G4String step;
203
204 const xercesc::DOMNamedNodeMap* const attributes = element->getAttributes();
205 XMLSize_t attributeCount = attributes->getLength();
206
207 for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
208 ++attribute_index)
209 {
210 xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
211
212 if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
213 {
214 continue;
215 }
216
217 const xercesc::DOMAttr* const attribute =
218 dynamic_cast<xercesc::DOMAttr*>(attribute_node);
219 if(!attribute)
220 {
221 G4Exception("G4GDMLRead::LoopRead()", "InvalidRead", FatalException,
222 "No attribute found!");
223 return;
224 }
225 const G4String attribute_name = Transcode(attribute->getName());
226 const G4String attribute_value = Transcode(attribute->getValue());
227
228 if(attribute_name == "for")
229 {
230 var = attribute_value;
231 }
232 else if(attribute_name == "from")
233 {
234 from = attribute_value;
235 }
236 else if(attribute_name == "to")
237 {
238 to = attribute_value;
239 }
240 else if(attribute_name == "step")
241 {
242 step = attribute_value;
243 }
244 }
245
246 if(var.empty())
247 {
248 G4Exception("G4GDMLRead::loopRead()", "InvalidRead", FatalException,
249 "No variable is determined for loop!");
250 }
251
252 if(!eval.IsVariable(var))
253 {
254 G4Exception("G4GDMLRead::loopRead()", "InvalidRead", FatalException,
255 "Variable is not defined in loop!");
256 }
257
258 G4int _var = eval.EvaluateInteger(var);
259 G4int _from = eval.EvaluateInteger(from);
260 G4int _to = eval.EvaluateInteger(to);
261 G4int _step = eval.EvaluateInteger(step);
262
263 if(!from.empty())
264 {
265 _var = _from;
266 }
267
268 if((_from < _to) && (_step <= 0))
269 {
270 G4Exception("G4GDMLRead::loopRead()", "InvalidRead", FatalException,
271 "Infinite loop!");
272 }
273 if((_from > _to) && (_step >= 0))
274 {
275 G4Exception("G4GDMLRead::loopRead()", "InvalidRead", FatalException,
276 "Infinite loop!");
277 }
278
279 ++inLoop;
280
281 while(_var <= _to)
282 {
283 eval.SetVariable(var, _var);
284 (this->*func)(element);
285 _var += _step;
286 ++loopCount;
287 }
288
289 --inLoop;
290 if(!inLoop)
291 {
292 loopCount = 0;
293 }
294}
295
296// --------------------------------------------------------------------
298 const xercesc::DOMElement* const auxiliaryElement)
299{
300 G4GDMLAuxStructType auxstruct = { "", "", "", 0 };
301 G4GDMLAuxListType* auxList = nullptr;
302
303 const xercesc::DOMNamedNodeMap* const attributes =
304 auxiliaryElement->getAttributes();
305 XMLSize_t attributeCount = attributes->getLength();
306
307 for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
308 ++attribute_index)
309 {
310 xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
311
312 if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
313 {
314 continue;
315 }
316
317 const xercesc::DOMAttr* const attribute =
318 dynamic_cast<xercesc::DOMAttr*>(attribute_node);
319 if(!attribute)
320 {
321 G4Exception("G4GDMLRead::AuxiliaryRead()", "InvalidRead", FatalException,
322 "No attribute found!");
323 return auxstruct;
324 }
325 const G4String attName = Transcode(attribute->getName());
326 const G4String attValue = Transcode(attribute->getValue());
327
328 if(attName == "auxtype")
329 {
330 auxstruct.type = attValue;
331 }
332 else if(attName == "auxvalue")
333 {
334 auxstruct.value = attValue;
335 }
336 else if(attName == "auxunit")
337 {
338 auxstruct.unit = attValue;
339 }
340 }
341
342 for(xercesc::DOMNode* iter = auxiliaryElement->getFirstChild();
343 iter != nullptr; iter = iter->getNextSibling())
344 {
345 if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
346 {
347 continue;
348 }
349
350 const xercesc::DOMElement* const child =
351 dynamic_cast<xercesc::DOMElement*>(iter);
352 if(!child)
353 {
354 G4Exception("G4GDMLRead::AuxiliaryRead()", "InvalidRead", FatalException,
355 "No child found!");
356 break;
357 }
358 const G4String tag = Transcode(child->getTagName());
359
360 if(tag == "auxiliary")
361 {
362 if(!auxList)
363 {
364 auxList = new G4GDMLAuxListType;
365 }
366 auxList->push_back(AuxiliaryRead(child));
367 }
368 }
369
370 if(auxList)
371 {
372 auxstruct.auxList = auxList;
373 }
374
375 return auxstruct;
376}
377
378// --------------------------------------------------------------------
379void G4GDMLRead::UserinfoRead(const xercesc::DOMElement* const userinfoElement)
380{
381#ifdef G4VERBOSE
382 G4cout << "G4GDML: Reading userinfo..." << G4endl;
383#endif
384 for(xercesc::DOMNode* iter = userinfoElement->getFirstChild();
385 iter != nullptr; iter = iter->getNextSibling())
386 {
387 if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
388 {
389 continue;
390 }
391
392 const xercesc::DOMElement* const child =
393 dynamic_cast<xercesc::DOMElement*>(iter);
394 if(!child)
395 {
396 G4Exception("G4GDMLRead::UserinfoRead()", "InvalidRead", FatalException,
397 "No child found!");
398 return;
399 }
400 const G4String tag = Transcode(child->getTagName());
401
402 if(tag == "auxiliary")
403 {
404 auxGlobalList.push_back(AuxiliaryRead(child));
405 }
406 else
407 {
408 G4String error_msg = "Unknown tag in structure: " + tag;
409 G4Exception("G4GDMLRead::UserinfoRead()", "ReadError", FatalException,
410 error_msg);
411 }
412 }
413}
414
415// --------------------------------------------------------------------
416void G4GDMLRead::ExtensionRead(const xercesc::DOMElement* const)
417{
418 G4String error_msg = "No handle to user-code for parsing extensions!";
419 G4Exception("G4GDMLRead::ExtensionRead()", "NotImplemented", JustWarning,
420 error_msg);
421}
422
423// --------------------------------------------------------------------
425{
426 return schema;
427}
428
429// --------------------------------------------------------------------
430void G4GDMLRead::SetSchemaFile(const G4String& schemaFile)
431{
432 schema = schemaFile;
433}
434
435// --------------------------------------------------------------------
436void G4GDMLRead::Read(const G4String& fileName, G4bool validation,
437 G4bool isModule, G4bool strip)
438{
439 dostrip = strip;
440#ifdef G4VERBOSE
441 if(isModule)
442 {
443 G4cout << "G4GDML: Reading module '" << fileName << "'..." << G4endl;
444 }
445 else
446 {
447 G4cout << "G4GDML: Reading '" << fileName << "'..." << G4endl;
448 }
449#endif
450 inLoop = 0;
451 validate = validation;
452
453 xercesc::ErrorHandler* handler = new G4GDMLErrorHandler(!validate);
454 xercesc::XercesDOMParser* parser = new xercesc::XercesDOMParser;
455
456 if(validate)
457 {
458 parser->setValidationScheme(xercesc::XercesDOMParser::Val_Always);
459
460 // Load alternative schema path if specified by user in
461 // 1. environment variable, or
462 // 2. `schema` data member, or
463 // Will fall back to default validation otherwise (`xsi:noNamespaceSchemaLocation` in input file)
464 if(auto schemaPath = G4GetEnv<G4String>("G4GDML_SCHEMA_FILE", schema); schemaPath != "")
465 {
466 // Pre-parse grammar to check it's present/valid
467 if(parser->loadGrammar(schemaPath.c_str(), xercesc::Grammar::SchemaGrammarType, true) != nullptr)
468 {
469 G4cout << "G4GDML: Loaded alternative schema URI: " << schemaPath << G4endl;
470 }
471 else
472 {
473 G4Exception("G4GDMLRead::Read()",
474 "InvalidGDMLSchemaFile",
476 G4String("Failed to load/parse schema file '" + schemaPath + "'").c_str());
477 }
478 parser->useCachedGrammarInParse(true);
479 // If the schema has been set manually then we want to ignore path set in input file, if any
480 parser->setExternalNoNamespaceSchemaLocation(schemaPath.c_str());
481 }
482 }
483 parser->setValidationSchemaFullChecking(validate);
484 parser->setCreateEntityReferenceNodes(false);
485 // Entities will be automatically resolved by Xerces
486
487 parser->setDoNamespaces(true);
488 parser->setDoSchema(validate);
489 parser->setErrorHandler(handler);
490
491 try
492 {
493 parser->parse(fileName.c_str());
494 } catch(const xercesc::XMLException& e)
495 {
496 G4cout << "G4GDML: " << Transcode(e.getMessage()) << G4endl;
497 } catch(const xercesc::DOMException& e)
498 {
499 G4cout << "G4GDML: " << Transcode(e.getMessage()) << G4endl;
500 }
501
502 xercesc::DOMDocument* doc = parser->getDocument();
503
504 if(doc == nullptr)
505 {
506 G4String error_msg = "Unable to open document: " + fileName;
507 G4Exception("G4GDMLRead::Read()", "InvalidRead", FatalException, error_msg);
508 return;
509 }
510 xercesc::DOMElement* element = doc->getDocumentElement();
511
512 if(element == nullptr )
513 {
514 std::ostringstream message;
515 message << "ERROR - Empty document or unable to validate schema!" << G4endl
516 << " Check Internet connection is ON in case of schema"
517 << G4endl
518 << " validation enabled and location defined as URL in"
519 << G4endl << " the GDML file - " << fileName
520 << " - being imported!" << G4endl
521 << " Otherwise, verify GDML schema server is reachable!";
522 G4Exception("G4GDMLRead::Read()", "InvalidRead", FatalException, message);
523 return;
524 }
525
526 for(xercesc::DOMNode* iter = element->getFirstChild(); iter != nullptr;
527 iter = iter->getNextSibling())
528 {
529 if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
530 {
531 continue;
532 }
533
534 const xercesc::DOMElement* const child =
535 dynamic_cast<xercesc::DOMElement*>(iter);
536 if(child == nullptr)
537 {
538 G4Exception("G4GDMLRead::Read()", "InvalidRead", FatalException,
539 "No child found!");
540 return;
541 }
542 const G4String tag = Transcode(child->getTagName());
543
544 if(tag == "define")
545 {
546 DefineRead(child);
547 }
548 else if(tag == "materials")
549 {
550 MaterialsRead(child);
551 }
552 else if(tag == "solids")
553 {
554 SolidsRead(child);
555 }
556 else if(tag == "setup")
557 {
558 SetupRead(child);
559 }
560 else if(tag == "structure")
561 {
562 StructureRead(child);
563 }
564 else if(tag == "userinfo")
565 {
566 UserinfoRead(child);
567 }
568 else if(tag == "extension")
569 {
570 ExtensionRead(child);
571 }
572 else
573 {
574 G4String error_msg = "Unknown tag in gdml: " + tag;
575 G4Exception("G4GDMLRead::Read()", "InvalidRead", FatalException,
576 error_msg);
577 }
578 }
579
580 delete parser;
581 delete handler;
582
583 if(isModule)
584 {
585#ifdef G4VERBOSE
586 G4cout << "G4GDML: Reading module '" << fileName << "' done!" << G4endl;
587#endif
588 }
589 else
590 {
591 G4cout << "G4GDML: Reading '" << fileName << "' done!" << G4endl;
592 if(strip)
593 {
594 StripNames();
595 }
596 }
597}
598
599// --------------------------------------------------------------------
601{
602 return &auxGlobalList;
603}
std::vector< G4Element * > G4ElementTable
_Tp G4GetEnv(const std::string &env_id, _Tp _default=_Tp())
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::vector< G4GDMLAuxStructType > G4GDMLAuxListType
std::vector< G4Material * > G4MaterialTable
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
static G4ElementTable * GetElementTable()
Definition G4Element.cc:389
void SetName(const G4String &name)
Definition G4Element.hh:179
const G4String & GetName() const
Definition G4Element.hh:115
void SetVariable(const G4String &, G4double)
G4bool IsVariable(const G4String &) const
G4int EvaluateInteger(const G4String &)
G4String SolveBrackets(const G4String &)
const G4String & GetSchemaFile() const
G4bool check
G4String Strip(const G4String &) const
G4bool validate
G4GDMLAuxStructType AuxiliaryRead(const xercesc::DOMElement *const auxElem)
G4bool dostrip
void GeneratePhysvolName(const G4String &, G4VPhysicalVolume *)
Definition G4GDMLRead.cc:89
virtual void SolidsRead(const xercesc::DOMElement *const)=0
void SetSchemaFile(const G4String &schemaFile)
G4String GenerateName(const G4String &name, G4bool strip=false)
Definition G4GDMLRead.cc:72
G4String schema
const G4GDMLAuxListType * GetAuxList() const
virtual void MaterialsRead(const xercesc::DOMElement *const)=0
void LoopRead(const xercesc::DOMElement *const, void(G4GDMLRead::*)(const xercesc::DOMElement *const))
void Read(const G4String &, G4bool validation, G4bool isModule, G4bool strip=true)
virtual void UserinfoRead(const xercesc::DOMElement *const)
virtual void SetupRead(const xercesc::DOMElement *const)=0
G4String Transcode(const XMLCh *const)
Definition G4GDMLRead.cc:57
void StripName(G4String &) const
virtual void ExtensionRead(const xercesc::DOMElement *const)
virtual void DefineRead(const xercesc::DOMElement *const)=0
virtual void StructureRead(const xercesc::DOMElement *const)=0
virtual ~G4GDMLRead()
Definition G4GDMLRead.cc:52
G4GDMLEvaluator eval
void OverlapCheck(G4bool)
Definition G4GDMLRead.cc:66
void StripNames() const
static G4LogicalVolumeStore * GetInstance()
void SetName(const G4String &pName)
const G4String & GetName() const
void SetName(const G4String &name)
static G4MaterialTable * GetMaterialTable()
const G4String & GetName() const
static G4PhysicalVolumeStore * GetInstance()
static G4SolidStore * GetInstance()
static G4UnitsTable & GetUnitsTable()
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
void SetName(const G4String &pName)
G4String GetName() const
void SetName(const G4String &name)
Definition G4VSolid.cc:127
std::vector< G4GDMLAuxStructType > * auxList