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 // G4GDMLWrite implementation 27 // 28 // Author: Zoltan Torzsok, November 2007 29 // ------------------------------------------- 30 31 #include <sys/stat.h> 32 #include <iostream> 33 34 #include "G4GDMLWrite.hh" 35 36 #include "G4LogicalVolume.hh" 37 #include "G4Transform3D.hh" 38 #include "G4PVDivision.hh" 39 40 G4bool G4GDMLWrite::addPointerToName = true; 41 42 // ------------------------------------------- 43 G4GDMLWrite::G4GDMLWrite() 44 { 45 } 46 47 // ------------------------------------------- 48 G4GDMLWrite::~G4GDMLWrite() 49 { 50 } 51 52 // ------------------------------------------- 53 G4bool G4GDMLWrite::FileExists(const G4String& 54 { 55 struct stat FileInfo; 56 return (stat(fname.c_str(), &FileInfo) == 0) 57 } 58 59 // ------------------------------------------- 60 G4GDMLWrite::VolumeMapType& G4GDMLWrite::Volum 61 { 62 static VolumeMapType instance; 63 return instance; 64 } 65 66 G4GDMLWrite::PhysVolumeMapType& G4GDMLWrite::P 67 { 68 static PhysVolumeMapType instance; 69 return instance; 70 } 71 72 // ------------------------------------------- 73 G4GDMLWrite::DepthMapType& G4GDMLWrite::DepthM 74 { 75 static DepthMapType instance; 76 return instance; 77 } 78 79 // ------------------------------------------- 80 void G4GDMLWrite::AddExtension(xercesc::DOMEle 81 const G4Logical 82 { 83 // Empty implementation. To be overwritten b 84 // related to attributes associated to volum 85 } 86 87 // ------------------------------------------- 88 void G4GDMLWrite::ExtensionWrite(xercesc::DOME 89 { 90 // Empty implementation. To be overwritten b 91 } 92 93 // ------------------------------------------- 94 void G4GDMLWrite::AddAuxInfo(G4GDMLAuxListType 95 xercesc::DOMEleme 96 { 97 for(auto iaux = auxInfoList->cbegin(); iaux 98 { 99 xercesc::DOMElement* auxiliaryElement = Ne 100 element->appendChild(auxiliaryElement); 101 102 auxiliaryElement->setAttributeNode(NewAttr 103 auxiliaryElement->setAttributeNode(NewAttr 104 if(((*iaux).unit) != "") 105 { 106 auxiliaryElement->setAttributeNode(NewAt 107 } 108 109 if(iaux->auxList) 110 { 111 AddAuxInfo(iaux->auxList, auxiliaryEleme 112 } 113 } 114 return; 115 } 116 117 // ------------------------------------------- 118 void G4GDMLWrite::UserinfoWrite(xercesc::DOMEl 119 { 120 if(auxList.size() > 0) 121 { 122 #ifdef G4VERBOSE 123 G4cout << "G4GDML: Writing userinfo..." << 124 #endif 125 userinfoElement = NewElement("userinfo"); 126 gdmlElement->appendChild(userinfoElement); 127 AddAuxInfo(&auxList, userinfoElement); 128 } 129 } 130 131 // ------------------------------------------- 132 G4String G4GDMLWrite::GenerateName(const G4Str 133 { 134 G4String nameOut; 135 std::stringstream stream; 136 stream << name; 137 if(addPointerToName) 138 { 139 stream << ptr; 140 }; 141 142 nameOut = G4String(stream.str()); 143 std::vector<char> toremove = { ' ', '/', ':' 144 for(auto c : toremove) 145 { 146 if(G4StrUtil::contains(nameOut, c)) 147 { 148 std::replace(nameOut.begin(), nameOut.en 149 } 150 } 151 return nameOut; 152 } 153 154 // ------------------------------------------- 155 xercesc::DOMAttr* G4GDMLWrite::NewAttribute(co 156 co 157 { 158 XMLCh* tempStr = NULL; 159 tempStr = xercesc::XMLString::transcode(name 160 xercesc::DOMAttr* att = doc->createAttribute 161 xercesc::XMLString::release(&tempStr); 162 163 tempStr = xercesc::XMLString::transcode(valu 164 att->setValue(tempStr); 165 xercesc::XMLString::release(&tempStr); 166 167 return att; 168 } 169 170 // ------------------------------------------- 171 xercesc::DOMAttr* G4GDMLWrite::NewAttribute(co 172 co 173 { 174 XMLCh* tempStr = NULL; 175 tempStr = xercesc::XMLString::transcode(name 176 xercesc::DOMAttr* att = doc->createAttribute 177 xercesc::XMLString::release(&tempStr); 178 179 std::ostringstream ostream; 180 ostream.precision(15); 181 ostream << value; 182 G4String str = ostream.str(); 183 184 tempStr = xercesc::XMLString::transcode(str) 185 att->setValue(tempStr); 186 xercesc::XMLString::release(&tempStr); 187 188 return att; 189 } 190 191 // ------------------------------------------- 192 xercesc::DOMElement* G4GDMLWrite::NewElement(c 193 { 194 XMLCh* tempStr = NULL; 195 tempStr = xercesc::XMLString::transcode(name 196 xercesc::DOMElement* elem = doc->createEleme 197 xercesc::XMLString::release(&tempStr); 198 199 return elem; 200 } 201 202 // ------------------------------------------- 203 G4Transform3D G4GDMLWrite::Write(const G4Strin 204 const G4Logic 205 const G4Strin 206 const G4int d 207 { 208 SchemaLocation = setSchemaLocation; 209 addPointerToName = refs; 210 #ifdef G4VERBOSE 211 if(depth == 0) 212 { 213 G4cout << "G4GDML: Writing '" << fname << 214 } 215 else 216 { 217 G4cout << "G4GDML: Writing module '" << fn 218 } 219 #endif 220 if(!overwriteOutputFile && FileExists(fname) 221 { 222 G4String ErrorMessage = "File '" + fname + 223 G4Exception("G4GDMLWrite::Write()", "Inval 224 ErrorMessage); 225 } 226 227 VolumeMap().clear(); // The module map is g 228 // so clear it only at 229 230 XMLCh* tempStr = NULL; 231 tempStr = xercesc::XMLString::transcode("LS" 232 xercesc::DOMImplementationRegistry::getDOMIm 233 xercesc::XMLString::release(&tempStr); 234 tempStr = xercesc::XMLString::transcode("Ran 235 xercesc::DOMImplementation* impl = 236 xercesc::DOMImplementationRegistry::getDOM 237 xercesc::XMLString::release(&tempStr); 238 tempStr = xercesc::XMLString::transcode("gdm 239 doc = impl->createDocu 240 xercesc::XMLString::release(&tempStr); 241 xercesc::DOMElement* gdml = doc->getDocument 242 243 #if XERCES_VERSION_MAJOR >= 3 244 // DOM L3 as per Xerces 3.0 API 245 xercesc::DOMLSSerializer* writer = 246 ((xercesc::DOMImplementationLS*) impl)->cr 247 248 xercesc::DOMConfiguration* dc = writer->getD 249 dc->setParameter(xercesc::XMLUni::fgDOMWRTFo 250 251 #else 252 253 xercesc::DOMWriter* writer = 254 ((xercesc::DOMImplementationLS*) impl)->cr 255 256 if(writer->canSetFeature(xercesc::XMLUni::fg 257 writer->setFeature(xercesc::XMLUni::fgDOMW 258 259 #endif 260 261 gdml->setAttributeNode( 262 NewAttribute("xmlns:xsi", "http://www.w3.o 263 gdml->setAttributeNode( 264 NewAttribute("xsi:noNamespaceSchemaLocatio 265 266 ExtensionWrite(gdml); 267 DefineWrite(gdml); 268 MaterialsWrite(gdml); 269 SolidsWrite(gdml); 270 StructureWrite(gdml); 271 UserinfoWrite(gdml); 272 SetupWrite(gdml, logvol); 273 274 G4Transform3D R = TraverseVolumeTree(logvol, 275 276 SurfacesWrite(); 277 xercesc::XMLFormatTarget* myFormTarget = 278 new xercesc::LocalFileFormatTarget(fname.c 279 280 try 281 { 282 #if XERCES_VERSION_MAJOR >= 3 283 // DOM L3 as per Xerces 3.0 API 284 xercesc::DOMLSOutput* theOutput = 285 ((xercesc::DOMImplementationLS*) impl)-> 286 theOutput->setByteStream(myFormTarget); 287 writer->write(doc, theOutput); 288 #else 289 writer->writeNode(myFormTarget, *doc); 290 #endif 291 } catch(const xercesc::XMLException& toCatch 292 { 293 char* message = xercesc::XMLString::transc 294 G4cout << "G4GDML: Exception message is: " 295 xercesc::XMLString::release(&message); 296 return G4Transform3D::Identity; 297 } catch(const xercesc::DOMException& toCatch 298 { 299 char* message = xercesc::XMLString::transc 300 G4cout << "G4GDML: Exception message is: " 301 xercesc::XMLString::release(&message); 302 return G4Transform3D::Identity; 303 } catch(...) 304 { 305 G4cout << "G4GDML: Unexpected Exception!" 306 return G4Transform3D::Identity; 307 } 308 309 delete myFormTarget; 310 writer->release(); 311 312 if(depth == 0) 313 { 314 G4cout << "G4GDML: Writing '" << fname << 315 } 316 else 317 { 318 #ifdef G4VERBOSE 319 G4cout << "G4GDML: Writing module '" << fn 320 #endif 321 } 322 323 return R; 324 } 325 326 // ------------------------------------------- 327 void G4GDMLWrite::AddModule(const G4VPhysicalV 328 { 329 G4String fname = GenerateName(physvol->GetNa 330 G4cout << "G4GDML: Adding module '" << fname 331 332 if(physvol == nullptr) 333 { 334 G4Exception("G4GDMLWrite::AddModule()", "I 335 "Invalid NULL pointer is speci 336 return; 337 } 338 if(dynamic_cast<const G4PVDivision*>(physvol 339 { 340 G4Exception("G4GDMLWrite::AddModule()", "I 341 "It is not possible to modular 342 return; 343 } 344 if(physvol->IsParameterised()) 345 { 346 G4Exception("G4GDMLWrite::AddModule()", "I 347 "It is not possible to modular 348 return; 349 } 350 if(physvol->IsReplicated()) 351 { 352 G4Exception("G4GDMLWrite::AddModule()", "I 353 "It is not possible to modular 354 return; 355 } 356 357 PvolumeMap()[physvol] = fname; 358 } 359 360 // ------------------------------------------- 361 void G4GDMLWrite::AddModule(const G4int depth) 362 { 363 if(depth < 0) 364 { 365 G4Exception("G4GDMLWrite::AddModule()", "I 366 "Depth must be a positive numb 367 } 368 if(DepthMap().find(depth) != DepthMap().end( 369 { 370 G4Exception("G4GDMLWrite::AddModule()", "I 371 "Adding module(s) at this dept 372 } 373 DepthMap()[depth] = 0; 374 } 375 376 // ------------------------------------------- 377 G4String G4GDMLWrite::Modularize(const G4VPhys 378 const G4int d 379 { 380 if(PvolumeMap().find(physvol) != PvolumeMap( 381 { 382 return PvolumeMap()[physvol]; // Modulari 383 } 384 385 if(DepthMap().find(depth) != DepthMap().cend 386 { 387 std::stringstream stream; 388 stream << "depth" << depth << "_module" << 389 DepthMap()[depth]++; // There can be more 390 return G4String(stream.str()); 391 } 392 393 return G4String(""); // Empty string for mo 394 // was requested at th 395 } 396 397 // ------------------------------------------- 398 void G4GDMLWrite::AddAuxiliary(G4GDMLAuxStruct 399 { 400 auxList.push_back(myaux); 401 } 402 403 // ------------------------------------------- 404 void G4GDMLWrite::SetOutputFileOverwrite(G4boo 405 { 406 overwriteOutputFile = flag; 407 } 408 409 // ------------------------------------------- 410 void G4GDMLWrite::SetAddPointerToName(G4bool s 411 { 412 addPointerToName = set; 413 } 414