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 // G4GDMLWriteStructure implementation 27 // 28 // Author: Zoltan Torzsok, November 2007 29 // ------------------------------------------- 30 31 #include "G4GDMLWriteStructure.hh" 32 #include "G4GDMLEvaluator.hh" 33 34 #include "G4Material.hh" 35 #include "G4ReflectedSolid.hh" 36 #include "G4DisplacedSolid.hh" 37 #include "G4LogicalVolumeStore.hh" 38 #include "G4PhysicalVolumeStore.hh" 39 #include "G4ReflectionFactory.hh" 40 #include "G4PVDivision.hh" 41 #include "G4PVReplica.hh" 42 #include "G4Region.hh" 43 #include "G4OpticalSurface.hh" 44 #include "G4LogicalSkinSurface.hh" 45 #include "G4LogicalBorderSurface.hh" 46 47 #include "G4ProductionCuts.hh" 48 #include "G4ProductionCutsTable.hh" 49 #include "G4Gamma.hh" 50 #include "G4Electron.hh" 51 #include "G4Positron.hh" 52 #include "G4Proton.hh" 53 54 #include "G4VSensitiveDetector.hh" 55 #include "G4AssemblyStore.hh" 56 #include "G4AssemblyVolume.hh" 57 58 G4int G4GDMLWriteStructure::levelNo = 0; // C 59 60 // ------------------------------------------- 61 G4GDMLWriteStructure::G4GDMLWriteStructure() 62 : G4GDMLWriteParamvol() 63 , maxLevel(INT_MAX) 64 { 65 reflFactory = G4ReflectionFactory::Instance( 66 } 67 68 // ------------------------------------------- 69 G4GDMLWriteStructure::~G4GDMLWriteStructure() 70 { 71 } 72 73 // ------------------------------------------- 74 void G4GDMLWriteStructure::DivisionvolWrite( 75 xercesc::DOMElement* volumeElement, const G4 76 { 77 EAxis axis = kUndefined; 78 G4int number = 0; 79 G4double width = 0.0; 80 G4double offset = 0.0; 81 G4bool consuming = false; 82 83 divisionvol->GetReplicationData(axis, number 84 axis = divisionvol->GetDivisionAxis(); 85 86 G4String unitString("mm"); 87 G4String axisString("kUndefined"); 88 if(axis == kXAxis) 89 { 90 axisString = "kXAxis"; 91 } 92 else if(axis == kYAxis) 93 { 94 axisString = "kYAxis"; 95 } 96 else if(axis == kZAxis) 97 { 98 axisString = "kZAxis"; 99 } 100 else if(axis == kRho) 101 { 102 axisString = "kRho"; 103 } 104 else if(axis == kPhi) 105 { 106 axisString = "kPhi"; 107 unitString = "rad"; 108 } 109 110 const G4String name = GenerateName(divisionv 111 const G4String volumeref = 112 GenerateName(divisionvol->GetLogicalVolume 113 divisionvol->GetLogicalVolume 114 115 xercesc::DOMElement* divisionvolElement = Ne 116 divisionvolElement->setAttributeNode(NewAttr 117 divisionvolElement->setAttributeNode(NewAttr 118 divisionvolElement->setAttributeNode(NewAttr 119 divisionvolElement->setAttributeNode(NewAttr 120 divisionvolElement->setAttributeNode(NewAttr 121 xercesc::DOMElement* volumerefElement = NewE 122 volumerefElement->setAttributeNode(NewAttrib 123 divisionvolElement->appendChild(volumerefEle 124 volumeElement->appendChild(divisionvolElemen 125 } 126 127 // ------------------------------------------- 128 void G4GDMLWriteStructure::PhysvolWrite(xerces 129 const 130 const 131 const 132 { 133 HepGeom::Scale3D scale; 134 HepGeom::Rotate3D rotate; 135 HepGeom::Translate3D translate; 136 137 T.getDecomposition(scale, rotate, translate) 138 139 const G4ThreeVector scl(scale(0, 0), scale(1 140 const G4ThreeVector rot = GetAngles(rotate.g 141 const G4ThreeVector pos = T.getTranslation() 142 143 const G4String name = GenerateName(physvo 144 const G4int copynumber = physvol->GetCopyNo( 145 146 xercesc::DOMElement* physvolElement = NewEle 147 physvolElement->setAttributeNode(NewAttribut 148 if(copynumber) 149 { 150 physvolElement->setAttributeNode(NewAttrib 151 } 152 153 volumeElement->appendChild(physvolElement); 154 155 G4LogicalVolume* lv; 156 // Is it reflected? 157 if(reflFactory->IsReflected(physvol->GetLogi 158 { 159 lv = reflFactory->GetConstituentLV(physvol 160 } 161 else 162 { 163 lv = physvol->GetLogicalVolume(); 164 } 165 166 const G4String volumeref = GenerateName(lv-> 167 168 if(ModuleName.empty()) 169 { 170 xercesc::DOMElement* volumerefElement = Ne 171 volumerefElement->setAttributeNode(NewAttr 172 physvolElement->appendChild(volumerefEleme 173 } 174 else 175 { 176 xercesc::DOMElement* fileElement = NewElem 177 fileElement->setAttributeNode(NewAttribute 178 fileElement->setAttributeNode(NewAttribute 179 physvolElement->appendChild(fileElement); 180 } 181 182 if(std::fabs(pos.x()) > kLinearPrecision || 183 std::fabs(pos.y()) > kLinearPrecision || 184 std::fabs(pos.z()) > kLinearPrecision) 185 { 186 PositionWrite(physvolElement, name + "_pos 187 } 188 if(std::fabs(rot.x()) > kAngularPrecision || 189 std::fabs(rot.y()) > kAngularPrecision || 190 std::fabs(rot.z()) > kAngularPrecision) 191 { 192 RotationWrite(physvolElement, name + "_rot 193 } 194 if(std::fabs(scl.x() - 1.0) > kRelativePreci 195 std::fabs(scl.y() - 1.0) > kRelativePreci 196 std::fabs(scl.z() - 1.0) > kRelativePreci 197 { 198 ScaleWrite(physvolElement, name + "_scl", 199 } 200 } 201 202 // ------------------------------------------- 203 void G4GDMLWriteStructure::ReplicavolWrite( 204 xercesc::DOMElement* volumeElement, const G4 205 { 206 EAxis axis = kUndefined; 207 G4int number = 0; 208 G4double width = 0.0; 209 G4double offset = 0.0; 210 G4bool consuming = false; 211 G4String unitString("mm"); 212 213 replicavol->GetReplicationData(axis, number, 214 215 const G4String volumeref = GenerateName( 216 replicavol->GetLogicalVolume()->GetName(), 217 218 xercesc::DOMElement* replicavolElement = New 219 replicavolElement->setAttributeNode(NewAttri 220 xercesc::DOMElement* volumerefElement = NewE 221 volumerefElement->setAttributeNode(NewAttrib 222 replicavolElement->appendChild(volumerefElem 223 xercesc::DOMElement* replicateElement = NewE 224 replicavolElement->appendChild(replicateElem 225 226 xercesc::DOMElement* dirElement = NewElement 227 if(axis == kXAxis) 228 { 229 dirElement->setAttributeNode(NewAttribute( 230 } 231 else if(axis == kYAxis) 232 { 233 dirElement->setAttributeNode(NewAttribute( 234 } 235 else if(axis == kZAxis) 236 { 237 dirElement->setAttributeNode(NewAttribute( 238 } 239 else if(axis == kRho) 240 { 241 dirElement->setAttributeNode(NewAttribute( 242 } 243 else if(axis == kPhi) 244 { 245 dirElement->setAttributeNode(NewAttribute( 246 unitString = "rad"; 247 } 248 replicateElement->appendChild(dirElement); 249 250 xercesc::DOMElement* widthElement = NewEleme 251 widthElement->setAttributeNode(NewAttribute( 252 widthElement->setAttributeNode(NewAttribute( 253 replicateElement->appendChild(widthElement); 254 255 xercesc::DOMElement* offsetElement = NewElem 256 offsetElement->setAttributeNode(NewAttribute 257 offsetElement->setAttributeNode(NewAttribute 258 replicateElement->appendChild(offsetElement) 259 260 volumeElement->appendChild(replicavolElement 261 } 262 263 // ------------------------------------------- 264 void G4GDMLWriteStructure::AssemblyWrite(xerce 265 const 266 { 267 G4AssemblyStore* assemblies = G4AssemblySto 268 G4AssemblyVolume* myassembly = assemblies->G 269 270 xercesc::DOMElement* assemblyElement = NewEl 271 G4String name = "Assembly_" + std::to_string 272 273 assemblyElement->setAttributeNode(NewAttribu 274 275 auto vit = myassembly->GetTripletsIterator() 276 277 G4int depth = 0; 278 const G4String ModuleName; 279 280 for(std::size_t i5 = 0; i5 < myassembly->Tot 281 { 282 G4LogicalVolume* lvol = (*vit).GetVolume() 283 if (lvol == nullptr) 284 { 285 G4String message = "Nested assemblies no 286 G4Exception("G4GDMLWriteStructure::Assem 287 FatalException, message); 288 return; 289 } 290 TraverseVolumeTree(lvol, depth + 1); 291 292 const G4ThreeVector rot = GetAngles((*vit) 293 const G4ThreeVector pos = (*vit).GetTransl 294 295 const G4String pname = 296 GenerateName((*vit).GetVolume()->GetName 297 298 xercesc::DOMElement* physvolElement = NewE 299 physvolElement->setAttributeNode(NewAttrib 300 301 assemblyElement->appendChild(physvolElemen 302 303 const G4String volumeref = 304 GenerateName((*vit).GetVolume()->GetName 305 306 xercesc::DOMElement* volumerefElement = Ne 307 volumerefElement->setAttributeNode(NewAttr 308 physvolElement->appendChild(volumerefEleme 309 310 if(std::fabs(pos.x()) > kLinearPrecision | 311 std::fabs(pos.y()) > kLinearPrecision | 312 std::fabs(pos.z()) > kLinearPrecision) 313 { 314 PositionWrite(physvolElement,name+"_posi 315 } 316 317 if(std::fabs(rot.x()) > kAngularPrecision 318 std::fabs(rot.y()) > kAngularPrecision 319 std::fabs(rot.z()) > kAngularPrecision) 320 { 321 RotationWrite(physvolElement,name+"_rota 322 } 323 ++vit; 324 } 325 326 volumeElement->appendChild(assemblyElement); 327 } 328 329 // ------------------------------------------- 330 void G4GDMLWriteStructure::BorderSurfaceCache( 331 const G4LogicalBorderSurface* const bsurf) 332 { 333 if(bsurf == nullptr) 334 { 335 return; 336 } 337 338 const G4SurfaceProperty* psurf = bsurf->GetS 339 340 // Generate the new element for border-surfa 341 // 342 const G4String& bsname = Generat 343 const G4String& psname = Generat 344 xercesc::DOMElement* borderElement = NewElem 345 borderElement->setAttributeNode(NewAttribute 346 borderElement->setAttributeNode(NewAttribute 347 348 const G4String volumeref1 = 349 GenerateName(bsurf->GetVolume1()->GetName( 350 const G4String volumeref2 = 351 GenerateName(bsurf->GetVolume2()->GetName( 352 xercesc::DOMElement* volumerefElement1 = New 353 xercesc::DOMElement* volumerefElement2 = New 354 volumerefElement1->setAttributeNode(NewAttri 355 volumerefElement2->setAttributeNode(NewAttri 356 borderElement->appendChild(volumerefElement1 357 borderElement->appendChild(volumerefElement2 358 359 if(FindOpticalSurface(psurf)) 360 { 361 const G4OpticalSurface* opsurf = 362 dynamic_cast<const G4OpticalSurface*>(ps 363 if(opsurf == nullptr) 364 { 365 G4Exception("G4GDMLWriteStructure::Borde 366 FatalException, "No optical 367 return; 368 } 369 OpticalSurfaceWrite(solidsElement, opsurf) 370 } 371 372 borderElementVec.push_back(borderElement); 373 } 374 375 // ------------------------------------------- 376 void G4GDMLWriteStructure::SkinSurfaceCache( 377 const G4LogicalSkinSurface* const ssurf) 378 { 379 if(ssurf == nullptr) 380 { 381 return; 382 } 383 384 const G4SurfaceProperty* psurf = ssurf->GetS 385 386 // Generate the new element for border-surfa 387 // 388 const G4String& ssname = GenerateN 389 const G4String& psname = GenerateN 390 xercesc::DOMElement* skinElement = NewElemen 391 skinElement->setAttributeNode(NewAttribute(" 392 skinElement->setAttributeNode(NewAttribute(" 393 394 const G4String volumeref = GenerateName(ssur 395 ssur 396 xercesc::DOMElement* volumerefElement = NewE 397 volumerefElement->setAttributeNode(NewAttrib 398 skinElement->appendChild(volumerefElement); 399 400 if(FindOpticalSurface(psurf)) 401 { 402 const G4OpticalSurface* opsurf = 403 dynamic_cast<const G4OpticalSurface*>(ps 404 if(opsurf == nullptr) 405 { 406 G4Exception("G4GDMLWriteStructure::SkinS 407 FatalException, "No optical 408 return; 409 } 410 OpticalSurfaceWrite(solidsElement, opsurf) 411 } 412 413 skinElementVec.push_back(skinElement); 414 } 415 416 // ------------------------------------------- 417 G4bool G4GDMLWriteStructure::FindOpticalSurfac 418 { 419 const G4OpticalSurface* osurf = dynamic_cast 420 auto pos = std::find(opt_vec.cbegin(), opt_v 421 if(pos != opt_vec.cend()) 422 { 423 return false; 424 } // item already created! 425 426 opt_vec.push_back(osurf); // cache it for f 427 return true; 428 } 429 430 // ------------------------------------------- 431 const G4LogicalSkinSurface* G4GDMLWriteStructu 432 const G4LogicalVolume* const lvol) 433 { 434 G4LogicalSkinSurface* surf = nullptr; 435 std::size_t nsurf = G4LogicalSkinSurface::Ge 436 if(nsurf) 437 { 438 const G4LogicalSkinSurfaceTable* stable = 439 G4LogicalSkinSurface::GetSurfaceTable(); 440 auto pos = stable->find(lvol); 441 if(pos != stable->cend()) 442 { 443 surf = pos->second; 444 } 445 } 446 return surf; 447 } 448 449 // ------------------------------------------- 450 const G4LogicalBorderSurface* G4GDMLWriteStruc 451 const G4VPhysicalVolume* const pvol) 452 { 453 G4LogicalBorderSurface* surf = nullptr; 454 std::size_t nsurf = G4LogicalBorderSurface:: 455 if(nsurf) 456 { 457 const G4LogicalBorderSurfaceTable* btable 458 G4LogicalBorderSurface::GetSurfaceTable( 459 for(auto pos = btable->cbegin(); pos != bt 460 { 461 if(pvol == pos->first.first) // just th 462 { // could b 463 surf = pos->second; // break; 464 BorderSurfaceCache(surf); 465 } 466 } 467 } 468 return surf; 469 } 470 471 // ------------------------------------------- 472 void G4GDMLWriteStructure::SurfacesWrite() 473 { 474 #ifdef G4VERBOSE 475 G4cout << "G4GDML: Writing surfaces..." << G 476 #endif 477 for(auto pos = skinElementVec.cbegin(); 478 pos != skinElementVec.cend(); ++pos 479 { 480 structureElement->appendChild(*pos); 481 } 482 for(auto pos = borderElementVec.cbegin(); 483 pos != borderElementVec.cend(); ++p 484 { 485 structureElement->appendChild(*pos); 486 } 487 } 488 489 // ------------------------------------------- 490 void G4GDMLWriteStructure::StructureWrite(xerc 491 { 492 #ifdef G4VERBOSE 493 G4cout << "G4GDML: Writing structure..." << 494 #endif 495 496 // filling the list of phys volumes that are 497 498 G4AssemblyStore* assemblies = G4AssemblyStor 499 500 for(auto it = assemblies->cbegin(); it != as 501 { 502 auto vit = (*it)->GetVolumesIterator(); 503 504 for(std::size_t i5 = 0; i5 < (*it)->TotalI 505 { 506 G4String pvname = (*vit)->GetName(); 507 std::size_t pos = pvname.find("_impr_") 508 G4String impID = pvname.substr(pos); 509 510 pos = impID.find("_"); 511 impID = impID.substr(0, pos); 512 513 assemblyVolMap[*vit] = (*it)->GetAssembl 514 imprintsMap[*vit] = std::atoi(impID.c 515 ++vit; 516 } 517 } 518 519 structureElement = NewElement("structure"); 520 gdmlElement->appendChild(structureElement); 521 } 522 523 // ------------------------------------------- 524 G4Transform3D G4GDMLWriteStructure::TraverseVo 525 const G4LogicalVolume* const volumePtr, cons 526 { 527 if(VolumeMap().find(volumePtr) != VolumeMap( 528 { 529 return VolumeMap()[volumePtr]; // Volume 530 } 531 532 G4VSolid* solidPtr = volumePtr->GetSolid(); 533 G4Transform3D R, invR; 534 G4int trans = 0; 535 536 std::map<const G4LogicalVolume*, G4GDMLAuxLi 537 538 ++levelNo; 539 540 while(true) // Solve possible displacement/ 541 { // of the referenced solid! 542 if(trans > maxTransforms) 543 { 544 G4String ErrorMessage = "Referenced soli 545 volumePtr->GetNa 546 "' was displaced 547 G4Exception("G4GDMLWriteStructure::Trave 548 FatalException, ErrorMessage 549 } 550 551 if(G4ReflectedSolid* refl = dynamic_cast<G 552 { 553 R = R * refl->GetTransform3D(); 554 solidPtr = refl->GetConstituentMovedSoli 555 ++trans; 556 continue; 557 } 558 559 if(G4DisplacedSolid* disp = dynamic_cast<G 560 { 561 R = R * G4Transform3D(disp->GetOb 562 disp->GetObjectTra 563 solidPtr = disp->GetConstituentMovedSoli 564 ++trans; 565 continue; 566 } 567 568 break; 569 } 570 571 // check if it is a reflected volume 572 G4LogicalVolume* tmplv = const_cast<G4Logica 573 574 if(reflFactory->IsReflected(tmplv)) 575 { 576 tmplv = reflFactory->GetConstituentLV(tmpl 577 if(VolumeMap().find(tmplv) != VolumeMap(). 578 { 579 return R; // Volume is already processe 580 } 581 } 582 583 // Only compute the inverse when necessary! 584 // 585 if(trans > 0) 586 { 587 invR = R.inverse(); 588 } 589 590 const G4String name = GenerateName(tmplv->Ge 591 592 G4String materialref = "NULL"; 593 594 if(volumePtr->GetMaterial()) 595 { 596 materialref = GenerateName(volumePtr->GetM 597 volumePtr->GetM 598 } 599 600 const G4String solidref = GenerateName(solid 601 602 xercesc::DOMElement* volumeElement = NewElem 603 volumeElement->setAttributeNode(NewAttribute 604 xercesc::DOMElement* materialrefElement = Ne 605 materialrefElement->setAttributeNode(NewAttr 606 volumeElement->appendChild(materialrefElemen 607 xercesc::DOMElement* solidrefElement = NewEl 608 solidrefElement->setAttributeNode(NewAttribu 609 volumeElement->appendChild(solidrefElement); 610 611 std::size_t daughterCount = volumePtr->GetNo 612 613 if(levelNo == maxLevel) // Stop exporting i 614 { 615 daughterCount = 0; 616 } 617 618 std::map<G4int, std::vector<G4int> > assembl 619 620 for(std::size_t i = 0; i < daughterCount; ++ 621 { 622 const G4VPhysicalVolume* const physvol = v 623 const G4String ModuleName = M 624 625 G4Transform3D daughterR; 626 627 if(ModuleName.empty()) // Check if subtre 628 { // a separate modu 629 daughterR = TraverseVolumeTree(physvol-> 630 } 631 else 632 { 633 G4GDMLWriteStructure writer; 634 daughterR = writer.Write(ModuleName, phy 635 SchemaLocation, 636 } 637 638 if(const G4PVDivision* const divisionvol = 639 dynamic_cast<const G4PVDivision*>(phy 640 { 641 if(!G4Transform3D::Identity.isNear(invR 642 { 643 G4String ErrorMessage = "Division volu 644 "' can not be 645 G4Exception("G4GDMLWriteStructure::Tra 646 "InvalidSetup", FatalExcep 647 } 648 DivisionvolWrite(volumeElement, division 649 } 650 else 651 { 652 if(physvol->IsParameterised()) // Is it 653 { 654 if(!G4Transform3D::Identity.isNear(inv 655 kRe 656 { 657 G4String ErrorMessage = "Parameteris 658 "' can not b 659 G4Exception("G4GDMLWriteStructure::T 660 "InvalidSetup", FatalExc 661 } 662 ParamvolWrite(volumeElement, physvol); 663 } 664 else 665 { 666 if(physvol->IsReplicated()) // Is it 667 { 668 if(!G4Transform3D::Identity.isNear(i 669 k 670 { 671 G4String ErrorMessage = "Replica v 672 "' can not 673 G4Exception("G4GDMLWriteStructure: 674 "InvalidSetup", FatalE 675 } 676 ReplicavolWrite(volumeElement, physv 677 } 678 else // Is it a physvol or an assembl 679 { 680 if(assemblyVolMap.find(physvol) != a 681 { 682 G4int assemblyID = assemblyVolMap[ 683 684 G4String assemblyref = "Assembly_" 685 686 // here I need to retrieve the imp 687 688 G4int imprintID = imprintsMap[phys 689 690 // there are 2 steps: 691 // 692 // 1) add assembly to the structur 693 // (but after the constituents vol 694 // 695 696 if(std::find(addedAssemblies.cbegi 697 assemblyID) == addedA 698 { 699 AssemblyWrite(structureElement, 700 addedAssemblies.push_back(assemb 701 assemblyIDToAddedImprints[assemb 702 } 703 704 // 2) add the assembly (as physica 705 // (but only once), using it's ori 706 // 707 708 // here I need a check if assembly 709 // mother volume 710 std::vector<G4int>& addedImprints 711 if(std::find(addedImprints.cbegin( 712 imprintID) == addedIm 713 { 714 G4String imprintname = "Imprint_ 715 imprintname = GenerateN 716 717 // I need to get those two from 718 // the assembly I have the impri 719 // 720 G4Transform3D& transf = G4Assemb 721 ->GetA 722 ->GetI 723 724 HepGeom::Scale3D scale; 725 HepGeom::Rotate3D rotate; 726 HepGeom::Translate3D translate; 727 728 transf.getDecomposition(scale, r 729 730 const G4ThreeVector scl(scale(0, 731 const G4ThreeVector rot = GetAng 732 const G4ThreeVector pos = transf 733 734 // here I need a normal physvol 735 736 xercesc::DOMElement* physvolElem 737 physvolElement->setAttributeNode 738 739 xercesc::DOMElement* volumerefEl 740 volumerefElement->setAttributeNo 741 physvolElement->appendChild(volu 742 743 if(std::fabs(pos.x()) > kLinearP 744 std::fabs(pos.y()) > kLinearP 745 std::fabs(pos.z()) > kLinearP 746 { 747 PositionWrite(physvolElement, 748 } 749 if(std::fabs(rot.x()) > kAngular 750 std::fabs(rot.y()) > kAngular 751 std::fabs(rot.z()) > kAngular 752 { 753 RotationWrite(physvolElement, 754 } 755 if(std::fabs(scl.x() - 1.0) > kR 756 std::fabs(scl.y() - 1.0) > kR 757 std::fabs(scl.z() - 1.0) > kR 758 { 759 ScaleWrite(physvolElement, nam 760 } 761 762 volumeElement->appendChild(physv 763 // 764 addedImprints.push_back(imprintI 765 } 766 } 767 else // not part of assembly, so a 768 { 769 G4RotationMatrix rot; 770 if(physvol->GetFrameRotation() != 771 { 772 rot = *(physvol->GetFrameRotatio 773 } 774 G4Transform3D P(rot, physvol->GetO 775 776 PhysvolWrite(volumeElement, physvo 777 ModuleName); 778 } 779 } 780 } 781 } 782 // BorderSurfaceCache(GetBorderSurface(phy 783 GetBorderSurface(physvol); 784 } 785 786 if(cexport) 787 { 788 ExportEnergyCuts(volumePtr); 789 } 790 // Add optional energy cuts 791 792 if(sdexport) 793 { 794 ExportSD(volumePtr); 795 } 796 // Add optional SDs 797 798 // Here write the auxiliary info 799 // 800 auxiter = auxmap.find(volumePtr); 801 if(auxiter != auxmap.cend()) 802 { 803 AddAuxInfo(&(auxiter->second), volumeEleme 804 } 805 806 structureElement->appendChild(volumeElement) 807 // Append the volume AFTER traversing the ch 808 // the order of volumes will be correct! 809 810 VolumeMap()[tmplv] = R; 811 812 AddExtension(volumeElement, volumePtr); 813 // Add any possible user defined extension a 814 815 AddMaterial(volumePtr->GetMaterial()); 816 // Add the involved materials and solids! 817 818 AddSolid(solidPtr); 819 820 SkinSurfaceCache(GetSkinSurface(volumePtr)); 821 822 return R; 823 } 824 825 // ------------------------------------------- 826 void G4GDMLWriteStructure::AddVolumeAuxiliary( 827 828 { 829 auto pos = auxmap.find(lvol); 830 831 if(pos == auxmap.cend()) 832 { 833 auxmap[lvol] = G4GDMLAuxListType(); 834 } 835 836 auxmap[lvol].push_back(myaux); 837 } 838 839 // ------------------------------------------- 840 void G4GDMLWriteStructure::SetEnergyCutsExport 841 { 842 cexport = fcuts; 843 } 844 845 // ------------------------------------------- 846 void G4GDMLWriteStructure::ExportEnergyCuts(co 847 { 848 G4GDMLEvaluator eval; 849 G4ProductionCuts* pcuts = lvol->GetRegio 850 G4ProductionCutsTable* ctab = G4ProductionCu 851 G4Gamma* gamma = G4Gamma::Gamma 852 G4Electron* eminus = G4Electron::El 853 G4Positron* eplus = G4Positron::Po 854 G4Proton* proton = G4Proton::Prot 855 856 G4double gamma_cut = ctab->ConvertRangeToEne 857 gamma, lvol->GetMaterial(), pcuts->GetProd 858 G4double eminus_cut = ctab->ConvertRangeToEn 859 eminus, lvol->GetMaterial(), pcuts->GetPro 860 G4double eplus_cut = ctab->ConvertRangeToEne 861 eplus, lvol->GetMaterial(), pcuts->GetProd 862 G4double proton_cut = ctab->ConvertRangeToEn 863 proton, lvol->GetMaterial(), pcuts->GetPro 864 865 G4GDMLAuxStructType gammainfo = { "gammaECu 866 eval.Conve 867 G4GDMLAuxStructType eminusinfo = { "electron 868 eval.Conv 869 0 }; 870 G4GDMLAuxStructType eplusinfo = { "positron 871 eval.Conve 872 G4GDMLAuxStructType protinfo = { "protonEC 873 eval.Conver 874 875 AddVolumeAuxiliary(gammainfo, lvol); 876 AddVolumeAuxiliary(eminusinfo, lvol); 877 AddVolumeAuxiliary(eplusinfo, lvol); 878 AddVolumeAuxiliary(protinfo, lvol); 879 } 880 881 // ------------------------------------------- 882 void G4GDMLWriteStructure::SetSDExport(G4bool 883 { 884 sdexport = fsd; 885 } 886 887 // ------------------------------------------- 888 void G4GDMLWriteStructure::ExportSD(const G4Lo 889 { 890 G4VSensitiveDetector* sd = lvol->GetMasterSe 891 892 if(sd != nullptr) 893 { 894 G4String SDname = sd->GetName(); 895 896 G4GDMLAuxStructType SDinfo = { "SensDet", 897 AddVolumeAuxiliary(SDinfo, lvol); 898 } 899 } 900 901 // ------------------------------------------- 902 G4int G4GDMLWriteStructure::GetMaxExportLevel( 903 { 904 return maxLevel; 905 } 906 907 // ------------------------------------------- 908 void G4GDMLWriteStructure::SetMaxExportLevel(G 909 { 910 if(level <= 0) 911 { 912 G4Exception("G4GDMLWriteStructure::Travers 913 FatalException, "Levels to exp 914 return; 915 } 916 maxLevel = level; 917 levelNo = 0; 918 } 919