Geant4-11
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
42// --------------------------------------------------------------------
44{
45 // Make sure units are defined.
47}
48
49// --------------------------------------------------------------------
51{
52}
53
54// --------------------------------------------------------------------
55G4String G4GDMLRead::Transcode(const XMLCh* const toTranscode)
56{
57 char* char_str = xercesc::XMLString::transcode(toTranscode);
58 G4String my_str(char_str);
59 xercesc::XMLString::release(&char_str);
60 return my_str;
61}
62
63// --------------------------------------------------------------------
65{
66 check = flag;
67}
68
69// --------------------------------------------------------------------
71{
72 G4String nameOut(nameIn);
73
74 if(inLoop > 0)
75 {
76 nameOut = eval.SolveBrackets(nameOut);
77 }
78 if(strip)
79 {
80 StripName(nameOut);
81 }
82
83 return nameOut;
84}
85
86// --------------------------------------------------------------------
88 G4VPhysicalVolume* physvol)
89{
90 G4String nameOut(nameIn);
91
92 if(nameIn.empty())
93 {
94 std::stringstream stream;
95 stream << physvol->GetLogicalVolume()->GetName() << "_PV";
96 nameOut = stream.str();
97 }
98 nameOut = eval.SolveBrackets(nameOut);
99
100 physvol->SetName(nameOut);
101}
102
103// --------------------------------------------------------------------
105{
106 G4String sname(name);
107 StripName(sname);
108 return sname;
109}
110
111// --------------------------------------------------------------------
113{
114 auto idx = name.find("0x");
115 if(idx != G4String::npos)
116 {
117 name.erase(idx);
118 }
119}
120
121// --------------------------------------------------------------------
123{
124 // Strips off names of volumes, solids elements and materials from possible
125 // reference pointers or IDs attached to their original identifiers.
126
130 const G4ElementTable* elements = G4Element::GetElementTable();
132
133 G4cout << "Stripping off GDML names of materials, solids and volumes ..."
134 << G4endl;
135
136 G4String sname;
137 std::size_t i;
138
139 // Solids...
140 //
141 for(i = 0; i < solids->size(); ++i)
142 {
143 G4VSolid* psol = (*solids)[i];
144 sname = psol->GetName();
145 StripName(sname);
146 psol->SetName(sname);
147 }
148 solids->UpdateMap();
149
150 // Logical volumes...
151 //
152 for(i = 0; i < lvols->size(); ++i)
153 {
154 G4LogicalVolume* lvol = (*lvols)[i];
155 sname = lvol->GetName();
156 StripName(sname);
157 lvol->SetName(sname);
158 }
159 lvols->UpdateMap();
160
161 // Physical volumes...
162 //
163 for(i = 0; i < pvols->size(); ++i)
164 {
165 G4VPhysicalVolume* pvol = (*pvols)[i];
166 sname = pvol->GetName();
167 StripName(sname);
168 pvol->SetName(sname);
169 }
170 pvols->UpdateMap();
171
172 // Materials...
173 //
174 for(i = 0; i < materials->size(); ++i)
175 {
176 G4Material* pmat = (*materials)[i];
177 sname = pmat->GetName();
178 StripName(sname);
179 pmat->SetName(sname);
180 }
181
182 // Elements...
183 //
184 for(i = 0; i < elements->size(); ++i)
185 {
186 G4Element* pelm = (*elements)[i];
187 sname = pelm->GetName();
188 StripName(sname);
189 pelm->SetName(sname);
190 }
191}
192
193// --------------------------------------------------------------------
194void G4GDMLRead::LoopRead( const xercesc::DOMElement* const element,
195 void (G4GDMLRead::*func)(const xercesc::DOMElement* const))
196{
197 G4String var;
198 G4String from;
199 G4String to;
200 G4String step;
201
202 const xercesc::DOMNamedNodeMap* const attributes = element->getAttributes();
203 XMLSize_t attributeCount = attributes->getLength();
204
205 for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
206 ++attribute_index)
207 {
208 xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
209
210 if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
211 {
212 continue;
213 }
214
215 const xercesc::DOMAttr* const attribute =
216 dynamic_cast<xercesc::DOMAttr*>(attribute_node);
217 if(!attribute)
218 {
219 G4Exception("G4GDMLRead::LoopRead()", "InvalidRead", FatalException,
220 "No attribute found!");
221 return;
222 }
223 const G4String attribute_name = Transcode(attribute->getName());
224 const G4String attribute_value = Transcode(attribute->getValue());
225
226 if(attribute_name == "for")
227 {
228 var = attribute_value;
229 }
230 else if(attribute_name == "from")
231 {
232 from = attribute_value;
233 }
234 else if(attribute_name == "to")
235 {
236 to = attribute_value;
237 }
238 else if(attribute_name == "step")
239 {
240 step = attribute_value;
241 }
242 }
243
244 if(var.empty())
245 {
246 G4Exception("G4GDMLRead::loopRead()", "InvalidRead", FatalException,
247 "No variable is determined for loop!");
248 }
249
250 if(!eval.IsVariable(var))
251 {
252 G4Exception("G4GDMLRead::loopRead()", "InvalidRead", FatalException,
253 "Variable is not defined in loop!");
254 }
255
256 G4int _var = eval.EvaluateInteger(var);
257 G4int _from = eval.EvaluateInteger(from);
258 G4int _to = eval.EvaluateInteger(to);
259 G4int _step = eval.EvaluateInteger(step);
260
261 if(!from.empty())
262 {
263 _var = _from;
264 }
265
266 if((_from < _to) && (_step <= 0))
267 {
268 G4Exception("G4GDMLRead::loopRead()", "InvalidRead", FatalException,
269 "Infinite loop!");
270 }
271 if((_from > _to) && (_step >= 0))
272 {
273 G4Exception("G4GDMLRead::loopRead()", "InvalidRead", FatalException,
274 "Infinite loop!");
275 }
276
277 ++inLoop;
278
279 while(_var <= _to)
280 {
281 eval.SetVariable(var, _var);
282 (this->*func)(element);
283 _var += _step;
284 ++loopCount;
285 }
286
287 --inLoop;
288 if(!inLoop)
289 {
290 loopCount = 0;
291 }
292}
293
294// --------------------------------------------------------------------
296 const xercesc::DOMElement* const auxiliaryElement)
297{
298 G4GDMLAuxStructType auxstruct = { "", "", "", 0 };
299 G4GDMLAuxListType* auxList = nullptr;
300
301 const xercesc::DOMNamedNodeMap* const attributes =
302 auxiliaryElement->getAttributes();
303 XMLSize_t attributeCount = attributes->getLength();
304
305 for(XMLSize_t attribute_index = 0; attribute_index < attributeCount;
306 ++attribute_index)
307 {
308 xercesc::DOMNode* attribute_node = attributes->item(attribute_index);
309
310 if(attribute_node->getNodeType() != xercesc::DOMNode::ATTRIBUTE_NODE)
311 {
312 continue;
313 }
314
315 const xercesc::DOMAttr* const attribute =
316 dynamic_cast<xercesc::DOMAttr*>(attribute_node);
317 if(!attribute)
318 {
319 G4Exception("G4GDMLRead::AuxiliaryRead()", "InvalidRead", FatalException,
320 "No attribute found!");
321 return auxstruct;
322 }
323 const G4String attName = Transcode(attribute->getName());
324 const G4String attValue = Transcode(attribute->getValue());
325
326 if(attName == "auxtype")
327 {
328 auxstruct.type = attValue;
329 }
330 else if(attName == "auxvalue")
331 {
332 auxstruct.value = attValue;
333 }
334 else if(attName == "auxunit")
335 {
336 auxstruct.unit = attValue;
337 }
338 }
339
340 for(xercesc::DOMNode* iter = auxiliaryElement->getFirstChild();
341 iter != nullptr; iter = iter->getNextSibling())
342 {
343 if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
344 {
345 continue;
346 }
347
348 const xercesc::DOMElement* const child =
349 dynamic_cast<xercesc::DOMElement*>(iter);
350 if(!child)
351 {
352 G4Exception("G4GDMLRead::AuxiliaryRead()", "InvalidRead", FatalException,
353 "No child found!");
354 break;
355 }
356 const G4String tag = Transcode(child->getTagName());
357
358 if(tag == "auxiliary")
359 {
360 if(!auxList)
361 {
362 auxList = new G4GDMLAuxListType;
363 }
364 auxList->push_back(AuxiliaryRead(child));
365 }
366 }
367
368 if(auxList)
369 {
370 auxstruct.auxList = auxList;
371 }
372
373 return auxstruct;
374}
375
376// --------------------------------------------------------------------
377void G4GDMLRead::UserinfoRead(const xercesc::DOMElement* const userinfoElement)
378{
379#ifdef G4VERBOSE
380 G4cout << "G4GDML: Reading userinfo..." << G4endl;
381#endif
382 for(xercesc::DOMNode* iter = userinfoElement->getFirstChild();
383 iter != nullptr; iter = iter->getNextSibling())
384 {
385 if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
386 {
387 continue;
388 }
389
390 const xercesc::DOMElement* const child =
391 dynamic_cast<xercesc::DOMElement*>(iter);
392 if(!child)
393 {
394 G4Exception("G4GDMLRead::UserinfoRead()", "InvalidRead", FatalException,
395 "No child found!");
396 return;
397 }
398 const G4String tag = Transcode(child->getTagName());
399
400 if(tag == "auxiliary")
401 {
402 auxGlobalList.push_back(AuxiliaryRead(child));
403 }
404 else
405 {
406 G4String error_msg = "Unknown tag in structure: " + tag;
407 G4Exception("G4GDMLRead::UserinfoRead()", "ReadError", FatalException,
408 error_msg);
409 }
410 }
411}
412
413// --------------------------------------------------------------------
414void G4GDMLRead::ExtensionRead(const xercesc::DOMElement* const)
415{
416 G4String error_msg = "No handle to user-code for parsing extensions!";
417 G4Exception("G4GDMLRead::ExtensionRead()", "NotImplemented", JustWarning,
418 error_msg);
419}
420
421// --------------------------------------------------------------------
422void G4GDMLRead::Read(const G4String& fileName, G4bool validation,
423 G4bool isModule, G4bool strip)
424{
425 dostrip = strip;
426#ifdef G4VERBOSE
427 if(isModule)
428 {
429 G4cout << "G4GDML: Reading module '" << fileName << "'..." << G4endl;
430 }
431 else
432 {
433 G4cout << "G4GDML: Reading '" << fileName << "'..." << G4endl;
434 }
435#endif
436 inLoop = 0;
437 validate = validation;
438
439 xercesc::ErrorHandler* handler = new G4GDMLErrorHandler(!validate);
440 xercesc::XercesDOMParser* parser = new xercesc::XercesDOMParser;
441
442 if(validate)
443 {
444 parser->setValidationScheme(xercesc::XercesDOMParser::Val_Always);
445 }
446 parser->setValidationSchemaFullChecking(validate);
447 parser->setCreateEntityReferenceNodes(false);
448 // Entities will be automatically resolved by Xerces
449
450 parser->setDoNamespaces(true);
451 parser->setDoSchema(validate);
452 parser->setErrorHandler(handler);
453
454 try
455 {
456 parser->parse(fileName.c_str());
457 } catch(const xercesc::XMLException& e)
458 {
459 G4cout << "G4GDML: " << Transcode(e.getMessage()) << G4endl;
460 } catch(const xercesc::DOMException& e)
461 {
462 G4cout << "G4GDML: " << Transcode(e.getMessage()) << G4endl;
463 }
464
465 xercesc::DOMDocument* doc = parser->getDocument();
466
467 if(doc == nullptr)
468 {
469 G4String error_msg = "Unable to open document: " + fileName;
470 G4Exception("G4GDMLRead::Read()", "InvalidRead", FatalException, error_msg);
471 return;
472 }
473 xercesc::DOMElement* element = doc->getDocumentElement();
474
475 if(element == nullptr )
476 {
477 std::ostringstream message;
478 message << "ERROR - Empty document or unable to validate schema!" << G4endl
479 << " Check Internet connection is ON in case of schema"
480 << G4endl
481 << " validation enabled and location defined as URL in"
482 << G4endl << " the GDML file - " << fileName
483 << " - being imported!" << G4endl
484 << " Otherwise, verify GDML schema server is reachable!";
485 G4Exception("G4GDMLRead::Read()", "InvalidRead", FatalException, message);
486 return;
487 }
488
489 for(xercesc::DOMNode* iter = element->getFirstChild(); iter != nullptr;
490 iter = iter->getNextSibling())
491 {
492 if(iter->getNodeType() != xercesc::DOMNode::ELEMENT_NODE)
493 {
494 continue;
495 }
496
497 const xercesc::DOMElement* const child =
498 dynamic_cast<xercesc::DOMElement*>(iter);
499 if(child == nullptr)
500 {
501 G4Exception("G4GDMLRead::Read()", "InvalidRead", FatalException,
502 "No child found!");
503 return;
504 }
505 const G4String tag = Transcode(child->getTagName());
506
507 if(tag == "define")
508 {
509 DefineRead(child);
510 }
511 else if(tag == "materials")
512 {
513 MaterialsRead(child);
514 }
515 else if(tag == "solids")
516 {
517 SolidsRead(child);
518 }
519 else if(tag == "setup")
520 {
521 SetupRead(child);
522 }
523 else if(tag == "structure")
524 {
525 StructureRead(child);
526 }
527 else if(tag == "userinfo")
528 {
529 UserinfoRead(child);
530 }
531 else if(tag == "extension")
532 {
533 ExtensionRead(child);
534 }
535 else
536 {
537 G4String error_msg = "Unknown tag in gdml: " + tag;
538 G4Exception("G4GDMLRead::Read()", "InvalidRead", FatalException,
539 error_msg);
540 }
541 }
542
543 delete parser;
544 delete handler;
545
546 if(isModule)
547 {
548#ifdef G4VERBOSE
549 G4cout << "G4GDML: Reading module '" << fileName << "' done!" << G4endl;
550#endif
551 }
552 else
553 {
554 G4cout << "G4GDML: Reading '" << fileName << "' done!" << G4endl;
555 if(strip)
556 {
557 StripNames();
558 }
559 }
560}
561
562// --------------------------------------------------------------------
564{
565 return &auxGlobalList;
566}
std::vector< G4Element * > G4ElementTable
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
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:57
G4GLOB_DLL std::ostream G4cout
static G4ElementTable * GetElementTable()
Definition: G4Element.cc:397
void SetName(const G4String &name)
Definition: G4Element.hh:215
const G4String & GetName() const
Definition: G4Element.hh:127
void SetVariable(const G4String &, G4double)
G4bool IsVariable(const G4String &) const
G4int EvaluateInteger(const G4String &)
G4String SolveBrackets(const G4String &)
G4int loopCount
Definition: G4GDMLRead.hh:163
G4bool check
Definition: G4GDMLRead.hh:158
G4String Strip(const G4String &) const
Definition: G4GDMLRead.cc:104
G4GDMLAuxListType auxGlobalList
Definition: G4GDMLRead.hh:164
G4bool validate
Definition: G4GDMLRead.hh:157
G4GDMLAuxStructType AuxiliaryRead(const xercesc::DOMElement *const auxElem)
Definition: G4GDMLRead.cc:295
G4bool dostrip
Definition: G4GDMLRead.hh:159
void GeneratePhysvolName(const G4String &, G4VPhysicalVolume *)
Definition: G4GDMLRead.cc:87
virtual void SolidsRead(const xercesc::DOMElement *const)=0
G4String GenerateName(const G4String &name, G4bool strip=false)
Definition: G4GDMLRead.cc:70
const G4GDMLAuxListType * GetAuxList() const
Definition: G4GDMLRead.cc:563
virtual void MaterialsRead(const xercesc::DOMElement *const)=0
void LoopRead(const xercesc::DOMElement *const, void(G4GDMLRead::*)(const xercesc::DOMElement *const))
Definition: G4GDMLRead.cc:194
void Read(const G4String &, G4bool validation, G4bool isModule, G4bool strip=true)
Definition: G4GDMLRead.cc:422
virtual void UserinfoRead(const xercesc::DOMElement *const)
Definition: G4GDMLRead.cc:377
virtual void SetupRead(const xercesc::DOMElement *const)=0
G4String Transcode(const XMLCh *const)
Definition: G4GDMLRead.cc:55
void StripName(G4String &) const
Definition: G4GDMLRead.cc:112
virtual void ExtensionRead(const xercesc::DOMElement *const)
Definition: G4GDMLRead.cc:414
virtual void DefineRead(const xercesc::DOMElement *const)=0
G4int inLoop
Definition: G4GDMLRead.hh:163
virtual void StructureRead(const xercesc::DOMElement *const)=0
virtual ~G4GDMLRead()
Definition: G4GDMLRead.cc:50
G4GDMLEvaluator eval
Definition: G4GDMLRead.hh:156
void OverlapCheck(G4bool)
Definition: G4GDMLRead.cc:64
void StripNames() const
Definition: G4GDMLRead.cc:122
static G4LogicalVolumeStore * GetInstance()
void SetName(const G4String &pName)
const G4String & GetName() const
void SetName(const G4String &name)
Definition: G4Material.hh:285
static G4MaterialTable * GetMaterialTable()
Definition: G4Material.cc:672
const G4String & GetName() const
Definition: G4Material.hh:173
static G4PhysicalVolumeStore * GetInstance()
void UpdateMap()
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
const char * name(G4int ptype)
void strip(G4String &str, char c=' ')
Remove leading and trailing characters from string.
std::vector< G4GDMLAuxStructType > * auxList
Definition: xmlparse.cc:187