Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 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" 39 #include "G4LogicalVolumeStore.hh" 40 #include "G4PhysicalVolumeStore.hh" 41 #include "G4EnvironmentUtils.hh" 42 #include "G4Exception.hh" 43 44 // ------------------------------------------- 45 G4GDMLRead::G4GDMLRead() 46 { 47 // Make sure units are defined. 48 G4UnitDefinition::GetUnitsTable(); 49 } 50 51 // ------------------------------------------- 52 G4GDMLRead::~G4GDMLRead() 53 { 54 } 55 56 // ------------------------------------------- 57 G4String G4GDMLRead::Transcode(const XMLCh* co 58 { 59 char* char_str = xercesc::XMLString::transco 60 G4String my_str(char_str); 61 xercesc::XMLString::release(&char_str); 62 return my_str; 63 } 64 65 // ------------------------------------------- 66 void G4GDMLRead::OverlapCheck(G4bool flag) 67 { 68 check = flag; 69 } 70 71 // ------------------------------------------- 72 G4String G4GDMLRead::GenerateName(const G4Stri 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 // ------------------------------------------- 89 void G4GDMLRead::GeneratePhysvolName(const G4S 90 G4VPhysic 91 { 92 G4String nameOut(nameIn); 93 94 if(nameIn.empty()) 95 { 96 std::stringstream stream; 97 stream << physvol->GetLogicalVolume()->Get 98 nameOut = stream.str(); 99 } 100 nameOut = eval.SolveBrackets(nameOut); 101 102 physvol->SetName(nameOut); 103 } 104 105 // ------------------------------------------- 106 G4String G4GDMLRead::Strip(const G4String& nam 107 { 108 G4String sname(name); 109 StripName(sname); 110 return sname; 111 } 112 113 // ------------------------------------------- 114 void G4GDMLRead::StripName(G4String& name) con 115 { 116 auto idx = name.find("0x"); 117 if(idx != G4String::npos) 118 { 119 name.erase(idx); 120 } 121 } 122 123 // ------------------------------------------- 124 void G4GDMLRead::StripNames() const 125 { 126 // Strips off names of volumes, solids eleme 127 // reference pointers or IDs attached to the 128 129 G4PhysicalVolumeStore* pvols = G4Physica 130 G4LogicalVolumeStore* lvols = G4Logical 131 G4SolidStore* solids = G4SolidSt 132 const G4ElementTable* elements = G4Element 133 const G4MaterialTable* materials = G4Materia 134 135 G4cout << "Stripping off GDML names of mater 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 // ------------------------------------------- 196 void G4GDMLRead::LoopRead( const xercesc::DOME 197 void (G4GDMLRead::*func)(const xercesc::DOME 198 { 199 G4String var; 200 G4String from; 201 G4String to; 202 G4String step; 203 204 const xercesc::DOMNamedNodeMap* const attrib 205 XMLSize_t attributeCount 206 207 for(XMLSize_t attribute_index = 0; attribute 208 ++attribute_index) 209 { 210 xercesc::DOMNode* attribute_node = attribu 211 212 if(attribute_node->getNodeType() != xerces 213 { 214 continue; 215 } 216 217 const xercesc::DOMAttr* const attribute = 218 dynamic_cast<xercesc::DOMAttr*>(attribut 219 if(!attribute) 220 { 221 G4Exception("G4GDMLRead::LoopRead()", "I 222 "No attribute found!"); 223 return; 224 } 225 const G4String attribute_name = Transcode 226 const G4String attribute_value = Transcode 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()", "Inv 249 "No variable is determined for 250 } 251 252 if(!eval.IsVariable(var)) 253 { 254 G4Exception("G4GDMLRead::loopRead()", "Inv 255 "Variable is not defined in lo 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()", "Inv 271 "Infinite loop!"); 272 } 273 if((_from > _to) && (_step >= 0)) 274 { 275 G4Exception("G4GDMLRead::loopRead()", "Inv 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 // ------------------------------------------- 297 G4GDMLAuxStructType G4GDMLRead::AuxiliaryRead( 298 const xercesc::DOMElement* const auxiliaryEl 299 { 300 G4GDMLAuxStructType auxstruct = { "", "", "" 301 G4GDMLAuxListType* auxList = nullptr; 302 303 const xercesc::DOMNamedNodeMap* const attrib 304 auxiliaryElement->getAttributes(); 305 XMLSize_t attributeCount = attributes->getLe 306 307 for(XMLSize_t attribute_index = 0; attribute 308 ++attribute_index) 309 { 310 xercesc::DOMNode* attribute_node = attribu 311 312 if(attribute_node->getNodeType() != xerces 313 { 314 continue; 315 } 316 317 const xercesc::DOMAttr* const attribute = 318 dynamic_cast<xercesc::DOMAttr*>(attribut 319 if(!attribute) 320 { 321 G4Exception("G4GDMLRead::AuxiliaryRead() 322 "No attribute found!"); 323 return auxstruct; 324 } 325 const G4String attName = Transcode(attrib 326 const G4String attValue = Transcode(attrib 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 = auxiliaryElemen 343 iter != nullptr; iter 344 { 345 if(iter->getNodeType() != xercesc::DOMNode 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() 355 "No child found!"); 356 break; 357 } 358 const G4String tag = Transcode(child->getT 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 // ------------------------------------------- 379 void G4GDMLRead::UserinfoRead(const xercesc::D 380 { 381 #ifdef G4VERBOSE 382 G4cout << "G4GDML: Reading userinfo..." << G 383 #endif 384 for(xercesc::DOMNode* iter = userinfoElement 385 iter != nullptr; iter 386 { 387 if(iter->getNodeType() != xercesc::DOMNode 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()" 397 "No child found!"); 398 return; 399 } 400 const G4String tag = Transcode(child->getT 401 402 if(tag == "auxiliary") 403 { 404 auxGlobalList.push_back(AuxiliaryRead(ch 405 } 406 else 407 { 408 G4String error_msg = "Unknown tag in str 409 G4Exception("G4GDMLRead::UserinfoRead()" 410 error_msg); 411 } 412 } 413 } 414 415 // ------------------------------------------- 416 void G4GDMLRead::ExtensionRead(const xercesc:: 417 { 418 G4String error_msg = "No handle to user-code 419 G4Exception("G4GDMLRead::ExtensionRead()", " 420 error_msg); 421 } 422 423 // ------------------------------------------- 424 const G4String& G4GDMLRead::GetSchemaFile() co 425 { 426 return schema; 427 } 428 429 // ------------------------------------------- 430 void G4GDMLRead::SetSchemaFile(const G4String& 431 { 432 schema = schemaFile; 433 } 434 435 // ------------------------------------------- 436 void G4GDMLRead::Read(const G4String& fileName 437 G4bool isModule, G4bool 438 { 439 dostrip = strip; 440 #ifdef G4VERBOSE 441 if(isModule) 442 { 443 G4cout << "G4GDML: Reading module '" << fi 444 } 445 else 446 { 447 G4cout << "G4GDML: Reading '" << fileName 448 } 449 #endif 450 inLoop = 0; 451 validate = validation; 452 453 xercesc::ErrorHandler* handler = new G4GDM 454 xercesc::XercesDOMParser* parser = new xerce 455 456 if(validate) 457 { 458 parser->setValidationScheme(xercesc::Xerce 459 460 // Load alternative schema path if specifi 461 // 1. environment variable, or 462 // 2. `schema` data member, or 463 // Will fall back to default validation ot 464 if(auto schemaPath = G4GetEnv<G4String>("G 465 { 466 // Pre-parse grammar to check it's prese 467 if(parser->loadGrammar(schemaPath.c_str( 468 { 469 G4cout << "G4GDML: Loaded alternative 470 } 471 else 472 { 473 G4Exception("G4GDMLRead::Read()", 474 "InvalidGDMLSchemaFile", 475 FatalException, 476 G4String("Failed to load/p 477 } 478 parser->useCachedGrammarInParse(true); 479 // If the schema has been set manually t 480 parser->setExternalNoNamespaceSchemaLoca 481 } 482 } 483 parser->setValidationSchemaFullChecking(vali 484 parser->setCreateEntityReferenceNodes(false) 485 // Entities will be automatically resolved b 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.getMes 497 } catch(const xercesc::DOMException& e) 498 { 499 G4cout << "G4GDML: " << Transcode(e.getMes 500 } 501 502 xercesc::DOMDocument* doc = parser->getDocum 503 504 if(doc == nullptr) 505 { 506 G4String error_msg = "Unable to open docum 507 G4Exception("G4GDMLRead::Read()", "Invalid 508 return; 509 } 510 xercesc::DOMElement* element = doc->getDocum 511 512 if(element == nullptr ) 513 { 514 std::ostringstream message; 515 message << "ERROR - Empty document or unab 516 << " Check Internet connect 517 << G4endl 518 << " validation enabled and 519 << G4endl << " the GDML fil 520 << " - being imported!" << G4endl 521 << " Otherwise, verify GDML 522 G4Exception("G4GDMLRead::Read()", "Invalid 523 return; 524 } 525 526 for(xercesc::DOMNode* iter = element->getFir 527 iter = iter->getNextSi 528 { 529 if(iter->getNodeType() != xercesc::DOMNode 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()", "Inval 539 "No child found!"); 540 return; 541 } 542 const G4String tag = Transcode(child->getT 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 gdm 575 G4Exception("G4GDMLRead::Read()", "Inval 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 '" << fi 587 #endif 588 } 589 else 590 { 591 G4cout << "G4GDML: Reading '" << fileName 592 if(strip) 593 { 594 StripNames(); 595 } 596 } 597 } 598 599 // ------------------------------------------- 600 const G4GDMLAuxListType* G4GDMLRead::GetAuxLis 601 { 602 return &auxGlobalList; 603 } 604