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