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 // G4GDMLWriteStructure implementation << 27 // 26 // 28 // Author: Zoltan Torzsok, November 2007 << 27 // $Id: G4GDMLWriteStructure.cc 91789 2015-08-06 08:14:46Z gcosmo $ >> 28 // >> 29 // class G4GDMLWriteStructure Implementation >> 30 // >> 31 // Original author: Zoltan Torzsok, November 2007 >> 32 // 29 // ------------------------------------------- 33 // -------------------------------------------------------------------- 30 34 31 #include "G4GDMLWriteStructure.hh" 35 #include "G4GDMLWriteStructure.hh" 32 #include "G4GDMLEvaluator.hh" 36 #include "G4GDMLEvaluator.hh" 33 37 34 #include "G4Material.hh" 38 #include "G4Material.hh" 35 #include "G4ReflectedSolid.hh" 39 #include "G4ReflectedSolid.hh" 36 #include "G4DisplacedSolid.hh" 40 #include "G4DisplacedSolid.hh" 37 #include "G4LogicalVolumeStore.hh" 41 #include "G4LogicalVolumeStore.hh" 38 #include "G4PhysicalVolumeStore.hh" 42 #include "G4PhysicalVolumeStore.hh" 39 #include "G4ReflectionFactory.hh" 43 #include "G4ReflectionFactory.hh" 40 #include "G4PVDivision.hh" 44 #include "G4PVDivision.hh" 41 #include "G4PVReplica.hh" 45 #include "G4PVReplica.hh" 42 #include "G4Region.hh" 46 #include "G4Region.hh" 43 #include "G4OpticalSurface.hh" 47 #include "G4OpticalSurface.hh" 44 #include "G4LogicalSkinSurface.hh" 48 #include "G4LogicalSkinSurface.hh" 45 #include "G4LogicalBorderSurface.hh" 49 #include "G4LogicalBorderSurface.hh" 46 50 47 #include "G4ProductionCuts.hh" 51 #include "G4ProductionCuts.hh" 48 #include "G4ProductionCutsTable.hh" 52 #include "G4ProductionCutsTable.hh" 49 #include "G4Gamma.hh" 53 #include "G4Gamma.hh" 50 #include "G4Electron.hh" 54 #include "G4Electron.hh" 51 #include "G4Positron.hh" 55 #include "G4Positron.hh" 52 #include "G4Proton.hh" 56 #include "G4Proton.hh" 53 57 54 #include "G4VSensitiveDetector.hh" << 55 #include "G4AssemblyStore.hh" << 56 #include "G4AssemblyVolume.hh" << 57 << 58 G4int G4GDMLWriteStructure::levelNo = 0; // C << 59 << 60 // ------------------------------------------- << 61 G4GDMLWriteStructure::G4GDMLWriteStructure() 58 G4GDMLWriteStructure::G4GDMLWriteStructure() 62 : G4GDMLWriteParamvol() << 59 : G4GDMLWriteParamvol(), cexport(false) 63 , maxLevel(INT_MAX) << 64 { 60 { 65 reflFactory = G4ReflectionFactory::Instance( 61 reflFactory = G4ReflectionFactory::Instance(); 66 } 62 } 67 63 68 // ------------------------------------------- << 69 G4GDMLWriteStructure::~G4GDMLWriteStructure() 64 G4GDMLWriteStructure::~G4GDMLWriteStructure() 70 { 65 { 71 } 66 } 72 67 73 // ------------------------------------------- << 68 void 74 void G4GDMLWriteStructure::DivisionvolWrite( << 69 G4GDMLWriteStructure::DivisionvolWrite(xercesc::DOMElement* volumeElement, 75 xercesc::DOMElement* volumeElement, const G4 << 70 const G4PVDivision* const divisionvol) 76 { << 71 { 77 EAxis axis = kUndefined; << 72 EAxis axis = kUndefined; 78 G4int number = 0; << 73 G4int number = 0; 79 G4double width = 0.0; << 74 G4double width = 0.0; 80 G4double offset = 0.0; << 75 G4double offset = 0.0; 81 G4bool consuming = false; << 76 G4bool consuming = false; 82 << 77 83 divisionvol->GetReplicationData(axis, number << 78 divisionvol->GetReplicationData(axis,number,width,offset,consuming); 84 axis = divisionvol->GetDivisionAxis(); << 79 axis = divisionvol->GetDivisionAxis(); 85 << 80 86 G4String unitString("mm"); << 81 G4String unitString("mm"); 87 G4String axisString("kUndefined"); << 82 G4String axisString("kUndefined"); 88 if(axis == kXAxis) << 83 if (axis==kXAxis) { axisString = "kXAxis"; } 89 { << 84 else if (axis==kYAxis) { axisString = "kYAxis"; } 90 axisString = "kXAxis"; << 85 else if (axis==kZAxis) { axisString = "kZAxis"; } 91 } << 86 else if (axis==kRho) { axisString = "kRho"; } 92 else if(axis == kYAxis) << 87 else if (axis==kPhi) { axisString = "kPhi"; unitString = "rad"; } 93 { << 88 94 axisString = "kYAxis"; << 89 const G4String name 95 } << 90 = GenerateName(divisionvol->GetName(),divisionvol); 96 else if(axis == kZAxis) << 91 const G4String volumeref 97 { << 92 = GenerateName(divisionvol->GetLogicalVolume()->GetName(), 98 axisString = "kZAxis"; << 93 divisionvol->GetLogicalVolume()); 99 } << 94 100 else if(axis == kRho) << 95 xercesc::DOMElement* divisionvolElement = NewElement("divisionvol"); 101 { << 96 divisionvolElement->setAttributeNode(NewAttribute("axis",axisString)); 102 axisString = "kRho"; << 97 divisionvolElement->setAttributeNode(NewAttribute("number",number)); 103 } << 98 divisionvolElement->setAttributeNode(NewAttribute("width",width)); 104 else if(axis == kPhi) << 99 divisionvolElement->setAttributeNode(NewAttribute("offset",offset)); 105 { << 100 divisionvolElement->setAttributeNode(NewAttribute("unit",unitString)); 106 axisString = "kPhi"; << 101 xercesc::DOMElement* volumerefElement = NewElement("volumeref"); 107 unitString = "rad"; << 102 volumerefElement->setAttributeNode(NewAttribute("ref",volumeref)); 108 } << 103 divisionvolElement->appendChild(volumerefElement); 109 << 104 volumeElement->appendChild(divisionvolElement); 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 } 105 } 126 106 127 // ------------------------------------------- << 128 void G4GDMLWriteStructure::PhysvolWrite(xerces 107 void G4GDMLWriteStructure::PhysvolWrite(xercesc::DOMElement* volumeElement, 129 const 108 const G4VPhysicalVolume* const physvol, 130 const 109 const G4Transform3D& T, 131 const 110 const G4String& ModuleName) 132 { 111 { 133 HepGeom::Scale3D scale; << 112 HepGeom::Scale3D scale; 134 HepGeom::Rotate3D rotate; << 113 HepGeom::Rotate3D rotate; 135 HepGeom::Translate3D translate; << 114 HepGeom::Translate3D translate; 136 << 115 137 T.getDecomposition(scale, rotate, translate) << 116 T.getDecomposition(scale,rotate,translate); 138 << 117 139 const G4ThreeVector scl(scale(0, 0), scale(1 << 118 const G4ThreeVector scl(scale(0,0),scale(1,1),scale(2,2)); 140 const G4ThreeVector rot = GetAngles(rotate.g << 119 const G4ThreeVector rot = GetAngles(rotate.getRotation()); 141 const G4ThreeVector pos = T.getTranslation() << 120 const G4ThreeVector pos = T.getTranslation(); 142 << 121 143 const G4String name = GenerateName(physvo << 122 const G4String name = GenerateName(physvol->GetName(),physvol); 144 const G4int copynumber = physvol->GetCopyNo( << 123 const G4int copynumber = physvol->GetCopyNo(); 145 << 124 146 xercesc::DOMElement* physvolElement = NewEle << 125 xercesc::DOMElement* physvolElement = NewElement("physvol"); 147 physvolElement->setAttributeNode(NewAttribut << 126 physvolElement->setAttributeNode(NewAttribute("name",name)); 148 if(copynumber) << 127 if (copynumber) physvolElement->setAttributeNode(NewAttribute("copynumber", copynumber)); 149 { << 128 150 physvolElement->setAttributeNode(NewAttrib << 129 volumeElement->appendChild(physvolElement); 151 } << 130 152 << 131 G4LogicalVolume* lv; 153 volumeElement->appendChild(physvolElement); << 132 // Is it reflected? 154 << 133 if (reflFactory->IsReflected(physvol->GetLogicalVolume())) 155 G4LogicalVolume* lv; << 134 { 156 // Is it reflected? << 135 lv = reflFactory->GetConstituentLV(physvol->GetLogicalVolume()); 157 if(reflFactory->IsReflected(physvol->GetLogi << 136 } 158 { << 137 else 159 lv = reflFactory->GetConstituentLV(physvol << 138 { 160 } << 139 lv = physvol->GetLogicalVolume(); 161 else << 140 } 162 { << 141 163 lv = physvol->GetLogicalVolume(); << 142 const G4String volumeref = GenerateName(lv->GetName(), lv); 164 } << 143 165 << 144 if (ModuleName.empty()) 166 const G4String volumeref = GenerateName(lv-> << 145 { 167 << 146 xercesc::DOMElement* volumerefElement = NewElement("volumeref"); 168 if(ModuleName.empty()) << 147 volumerefElement->setAttributeNode(NewAttribute("ref",volumeref)); 169 { << 148 physvolElement->appendChild(volumerefElement); 170 xercesc::DOMElement* volumerefElement = Ne << 149 } 171 volumerefElement->setAttributeNode(NewAttr << 150 else 172 physvolElement->appendChild(volumerefEleme << 151 { 173 } << 152 xercesc::DOMElement* fileElement = NewElement("file"); 174 else << 153 fileElement->setAttributeNode(NewAttribute("name",ModuleName)); 175 { << 154 fileElement->setAttributeNode(NewAttribute("volname",volumeref)); 176 xercesc::DOMElement* fileElement = NewElem << 155 physvolElement->appendChild(fileElement); 177 fileElement->setAttributeNode(NewAttribute << 156 } 178 fileElement->setAttributeNode(NewAttribute << 157 179 physvolElement->appendChild(fileElement); << 158 if (std::fabs(pos.x()) > kLinearPrecision 180 } << 159 || std::fabs(pos.y()) > kLinearPrecision 181 << 160 || std::fabs(pos.z()) > kLinearPrecision) 182 if(std::fabs(pos.x()) > kLinearPrecision || << 161 { 183 std::fabs(pos.y()) > kLinearPrecision || << 162 PositionWrite(physvolElement,name+"_pos",pos); 184 std::fabs(pos.z()) > kLinearPrecision) << 163 } 185 { << 164 if (std::fabs(rot.x()) > kAngularPrecision 186 PositionWrite(physvolElement, name + "_pos << 165 || std::fabs(rot.y()) > kAngularPrecision 187 } << 166 || std::fabs(rot.z()) > kAngularPrecision) 188 if(std::fabs(rot.x()) > kAngularPrecision || << 167 { 189 std::fabs(rot.y()) > kAngularPrecision || << 168 RotationWrite(physvolElement,name+"_rot",rot); 190 std::fabs(rot.z()) > kAngularPrecision) << 169 } 191 { << 170 if (std::fabs(scl.x()-1.0) > kRelativePrecision 192 RotationWrite(physvolElement, name + "_rot << 171 || std::fabs(scl.y()-1.0) > kRelativePrecision 193 } << 172 || std::fabs(scl.z()-1.0) > kRelativePrecision) 194 if(std::fabs(scl.x() - 1.0) > kRelativePreci << 173 { 195 std::fabs(scl.y() - 1.0) > kRelativePreci << 174 ScaleWrite(physvolElement,name+"_scl",scl); 196 std::fabs(scl.z() - 1.0) > kRelativePreci << 175 } 197 { << 176 } 198 ScaleWrite(physvolElement, name + "_scl", << 177 199 } << 178 void G4GDMLWriteStructure::ReplicavolWrite(xercesc::DOMElement* volumeElement, 200 } << 179 const G4VPhysicalVolume* const replicavol) 201 << 180 { 202 // ------------------------------------------- << 181 EAxis axis = kUndefined; 203 void G4GDMLWriteStructure::ReplicavolWrite( << 182 G4int number = 0; 204 xercesc::DOMElement* volumeElement, const G4 << 183 G4double width = 0.0; 205 { << 184 G4double offset = 0.0; 206 EAxis axis = kUndefined; << 185 G4bool consuming = false; 207 G4int number = 0; << 186 G4String unitString("mm"); 208 G4double width = 0.0; << 187 209 G4double offset = 0.0; << 188 replicavol->GetReplicationData(axis,number,width,offset,consuming); 210 G4bool consuming = false; << 189 211 G4String unitString("mm"); << 190 const G4String volumeref 212 << 191 = GenerateName(replicavol->GetLogicalVolume()->GetName(), 213 replicavol->GetReplicationData(axis, number, << 192 replicavol->GetLogicalVolume()); 214 << 193 215 const G4String volumeref = GenerateName( << 194 xercesc::DOMElement* replicavolElement = NewElement("replicavol"); 216 replicavol->GetLogicalVolume()->GetName(), << 195 replicavolElement->setAttributeNode(NewAttribute("number",number)); 217 << 196 xercesc::DOMElement* volumerefElement = NewElement("volumeref"); 218 xercesc::DOMElement* replicavolElement = New << 197 volumerefElement->setAttributeNode(NewAttribute("ref",volumeref)); 219 replicavolElement->setAttributeNode(NewAttri << 198 replicavolElement->appendChild(volumerefElement); 220 xercesc::DOMElement* volumerefElement = NewE << 199 xercesc::DOMElement* replicateElement = NewElement("replicate_along_axis"); 221 volumerefElement->setAttributeNode(NewAttrib << 200 replicavolElement->appendChild(replicateElement); 222 replicavolElement->appendChild(volumerefElem << 201 223 xercesc::DOMElement* replicateElement = NewE << 202 xercesc::DOMElement* dirElement = NewElement("direction"); 224 replicavolElement->appendChild(replicateElem << 203 if(axis==kXAxis) 225 << 204 { dirElement->setAttributeNode(NewAttribute("x","1")); } 226 xercesc::DOMElement* dirElement = NewElement << 205 else if(axis==kYAxis) 227 if(axis == kXAxis) << 206 { dirElement->setAttributeNode(NewAttribute("y","1")); } 228 { << 207 else if(axis==kZAxis) 229 dirElement->setAttributeNode(NewAttribute( << 208 { dirElement->setAttributeNode(NewAttribute("z","1")); } 230 } << 209 else if(axis==kRho) 231 else if(axis == kYAxis) << 210 { dirElement->setAttributeNode(NewAttribute("rho","1")); } 232 { << 211 else if(axis==kPhi) 233 dirElement->setAttributeNode(NewAttribute( << 212 { dirElement->setAttributeNode(NewAttribute("phi","1")); 234 } << 213 unitString="rad"; } 235 else if(axis == kZAxis) << 214 replicateElement->appendChild(dirElement); 236 { << 215 237 dirElement->setAttributeNode(NewAttribute( << 216 xercesc::DOMElement* widthElement = NewElement("width"); 238 } << 217 widthElement->setAttributeNode(NewAttribute("value",width)); 239 else if(axis == kRho) << 218 widthElement->setAttributeNode(NewAttribute("unit",unitString)); 240 { << 219 replicateElement->appendChild(widthElement); 241 dirElement->setAttributeNode(NewAttribute( << 220 242 } << 221 xercesc::DOMElement* offsetElement = NewElement("offset"); 243 else if(axis == kPhi) << 222 offsetElement->setAttributeNode(NewAttribute("value",offset)); 244 { << 223 offsetElement->setAttributeNode(NewAttribute("unit",unitString)); 245 dirElement->setAttributeNode(NewAttribute( << 224 replicateElement->appendChild(offsetElement); 246 unitString = "rad"; << 225 247 } << 226 volumeElement->appendChild(replicavolElement); 248 replicateElement->appendChild(dirElement); << 227 } 249 << 228 250 xercesc::DOMElement* widthElement = NewEleme << 229 void G4GDMLWriteStructure:: 251 widthElement->setAttributeNode(NewAttribute( << 230 BorderSurfaceCache(const G4LogicalBorderSurface* const bsurf) 252 widthElement->setAttributeNode(NewAttribute( << 231 { 253 replicateElement->appendChild(widthElement); << 232 if (!bsurf) { return; } 254 << 233 255 xercesc::DOMElement* offsetElement = NewElem << 234 const G4SurfaceProperty* psurf = bsurf->GetSurfaceProperty(); 256 offsetElement->setAttributeNode(NewAttribute << 235 257 offsetElement->setAttributeNode(NewAttribute << 236 // Generate the new element for border-surface 258 replicateElement->appendChild(offsetElement) << 237 // >> 238 xercesc::DOMElement* borderElement = NewElement("bordersurface"); >> 239 borderElement->setAttributeNode(NewAttribute("name", bsurf->GetName())); >> 240 borderElement->setAttributeNode(NewAttribute("surfaceproperty", >> 241 psurf->GetName())); >> 242 >> 243 const G4String volumeref1 = GenerateName(bsurf->GetVolume1()->GetName(), >> 244 bsurf->GetVolume1()); >> 245 const G4String volumeref2 = GenerateName(bsurf->GetVolume2()->GetName(), >> 246 bsurf->GetVolume2()); >> 247 xercesc::DOMElement* volumerefElement1 = NewElement("physvolref"); >> 248 xercesc::DOMElement* volumerefElement2 = NewElement("physvolref"); >> 249 volumerefElement1->setAttributeNode(NewAttribute("ref",volumeref1)); >> 250 volumerefElement2->setAttributeNode(NewAttribute("ref",volumeref2)); >> 251 borderElement->appendChild(volumerefElement1); >> 252 borderElement->appendChild(volumerefElement2); >> 253 >> 254 if (FindOpticalSurface(psurf)) >> 255 { >> 256 const G4OpticalSurface* opsurf = >> 257 dynamic_cast<const G4OpticalSurface*>(psurf); >> 258 if (!opsurf) >> 259 { >> 260 G4Exception("G4GDMLWriteStructure::BorderSurfaceCache()", >> 261 "InvalidSetup", FatalException, "No optical surface found!"); >> 262 return; >> 263 } >> 264 OpticalSurfaceWrite(solidsElement, opsurf); >> 265 } >> 266 >> 267 borderElementVec.push_back(borderElement); >> 268 } >> 269 >> 270 void G4GDMLWriteStructure:: >> 271 SkinSurfaceCache(const G4LogicalSkinSurface* const ssurf) >> 272 { >> 273 if (!ssurf) { return; } >> 274 >> 275 const G4SurfaceProperty* psurf = ssurf->GetSurfaceProperty(); >> 276 >> 277 // Generate the new element for border-surface >> 278 // >> 279 xercesc::DOMElement* skinElement = NewElement("skinsurface"); >> 280 skinElement->setAttributeNode(NewAttribute("name", ssurf->GetName())); >> 281 skinElement->setAttributeNode(NewAttribute("surfaceproperty", >> 282 psurf->GetName())); >> 283 >> 284 const G4String volumeref = GenerateName(ssurf->GetLogicalVolume()->GetName(), >> 285 ssurf->GetLogicalVolume()); >> 286 xercesc::DOMElement* volumerefElement = NewElement("volumeref"); >> 287 volumerefElement->setAttributeNode(NewAttribute("ref",volumeref)); >> 288 skinElement->appendChild(volumerefElement); >> 289 >> 290 if (FindOpticalSurface(psurf)) >> 291 { >> 292 const G4OpticalSurface* opsurf = >> 293 dynamic_cast<const G4OpticalSurface*>(psurf); >> 294 if (!opsurf) >> 295 { >> 296 G4Exception("G4GDMLWriteStructure::SkinSurfaceCache()", >> 297 "InvalidSetup", FatalException, "No optical surface found!"); >> 298 return; >> 299 } >> 300 OpticalSurfaceWrite(solidsElement, opsurf); >> 301 } 259 302 260 volumeElement->appendChild(replicavolElement << 303 skinElementVec.push_back(skinElement); 261 } 304 } 262 305 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 306 G4bool G4GDMLWriteStructure::FindOpticalSurface(const G4SurfaceProperty* psurf) 418 { 307 { 419 const G4OpticalSurface* osurf = dynamic_cast << 308 const G4OpticalSurface* osurf = dynamic_cast<const G4OpticalSurface*>(psurf); 420 auto pos = std::find(opt_vec.cbegin(), opt_v << 309 std::vector<const G4OpticalSurface*>::const_iterator pos; 421 if(pos != opt_vec.cend()) << 310 pos = std::find(opt_vec.begin(), opt_vec.end(), osurf); 422 { << 311 if (pos != opt_vec.end()) { return false; } // item already created! 423 return false; << 424 } // item already created! << 425 312 426 opt_vec.push_back(osurf); // cache it for f << 313 opt_vec.push_back(osurf); // cache it for future reference 427 return true; << 314 return true; 428 } 315 } 429 316 430 // ------------------------------------------- << 317 const G4LogicalSkinSurface* 431 const G4LogicalSkinSurface* G4GDMLWriteStructu << 318 G4GDMLWriteStructure::GetSkinSurface(const G4LogicalVolume* const lvol) 432 const G4LogicalVolume* const lvol) << 433 { 319 { 434 G4LogicalSkinSurface* surf = nullptr; << 320 G4LogicalSkinSurface* surf = 0; 435 std::size_t nsurf = G4LogicalSkinSurface::Ge << 321 G4int nsurf = G4LogicalSkinSurface::GetNumberOfSkinSurfaces(); 436 if(nsurf) << 322 if (nsurf) 437 { 323 { 438 const G4LogicalSkinSurfaceTable* stable = 324 const G4LogicalSkinSurfaceTable* stable = 439 G4LogicalSkinSurface::GetSurfaceTable(); << 325 G4LogicalSkinSurface::GetSurfaceTable(); 440 auto pos = stable->find(lvol); << 326 std::vector<G4LogicalSkinSurface*>::const_iterator pos; 441 if(pos != stable->cend()) << 327 for (pos = stable->begin(); pos != stable->end(); pos++) 442 { 328 { 443 surf = pos->second; << 329 if (lvol == (*pos)->GetLogicalVolume()) >> 330 { >> 331 surf = *pos; break; >> 332 } 444 } 333 } 445 } 334 } 446 return surf; 335 return surf; 447 } 336 } 448 337 449 // ------------------------------------------- << 338 const G4LogicalBorderSurface* 450 const G4LogicalBorderSurface* G4GDMLWriteStruc << 339 G4GDMLWriteStructure::GetBorderSurface(const G4VPhysicalVolume* const pvol) 451 const G4VPhysicalVolume* const pvol) << 452 { 340 { 453 G4LogicalBorderSurface* surf = nullptr; << 341 G4LogicalBorderSurface* surf = 0; 454 std::size_t nsurf = G4LogicalBorderSurface:: << 342 G4int nsurf = G4LogicalBorderSurface::GetNumberOfBorderSurfaces(); 455 if(nsurf) << 343 if (nsurf) 456 { 344 { 457 const G4LogicalBorderSurfaceTable* btable 345 const G4LogicalBorderSurfaceTable* btable = 458 G4LogicalBorderSurface::GetSurfaceTable( << 346 G4LogicalBorderSurface::GetSurfaceTable(); 459 for(auto pos = btable->cbegin(); pos != bt << 347 std::vector<G4LogicalBorderSurface*>::const_iterator pos; 460 { << 348 for (pos = btable->begin(); pos != btable->end(); pos++) 461 if(pvol == pos->first.first) // just th << 349 { 462 { // could b << 350 if (pvol == (*pos)->GetVolume1()) // just the first in the couple 463 surf = pos->second; // break; << 351 { // is enough 464 BorderSurfaceCache(surf); << 352 surf = *pos; break; 465 } 353 } 466 } 354 } 467 } 355 } 468 return surf; 356 return surf; 469 } 357 } 470 358 471 // ------------------------------------------- << 472 void G4GDMLWriteStructure::SurfacesWrite() 359 void G4GDMLWriteStructure::SurfacesWrite() 473 { 360 { 474 #ifdef G4VERBOSE << 361 G4cout << "G4GDML: Writing surfaces..." << G4endl; 475 G4cout << "G4GDML: Writing surfaces..." << G << 362 476 #endif << 363 std::vector<xercesc::DOMElement*>::const_iterator pos; 477 for(auto pos = skinElementVec.cbegin(); << 364 for (pos = skinElementVec.begin(); pos != skinElementVec.end(); pos++) 478 pos != skinElementVec.cend(); ++pos << 365 { 479 { << 366 structureElement->appendChild(*pos); 480 structureElement->appendChild(*pos); << 367 } 481 } << 368 for (pos = borderElementVec.begin(); pos != borderElementVec.end(); pos++) 482 for(auto pos = borderElementVec.cbegin(); << 369 { 483 pos != borderElementVec.cend(); ++p << 370 structureElement->appendChild(*pos); 484 { << 371 } 485 structureElement->appendChild(*pos); << 486 } << 487 } 372 } 488 373 489 // ------------------------------------------- << 490 void G4GDMLWriteStructure::StructureWrite(xerc 374 void G4GDMLWriteStructure::StructureWrite(xercesc::DOMElement* gdmlElement) 491 { 375 { 492 #ifdef G4VERBOSE << 376 G4cout << "G4GDML: Writing structure..." << G4endl; 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 377 504 for(std::size_t i5 = 0; i5 < (*it)->TotalI << 378 structureElement = NewElement("structure"); 505 { << 379 gdmlElement->appendChild(structureElement); 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 } 380 } 522 381 523 // ------------------------------------------- << 382 G4Transform3D G4GDMLWriteStructure:: 524 G4Transform3D G4GDMLWriteStructure::TraverseVo << 383 TraverseVolumeTree(const G4LogicalVolume* const volumePtr, const G4int depth) 525 const G4LogicalVolume* const volumePtr, cons << 526 { 384 { 527 if(VolumeMap().find(volumePtr) != VolumeMap( << 385 if (VolumeMap().find(volumePtr) != VolumeMap().end()) 528 { << 386 { 529 return VolumeMap()[volumePtr]; // Volume << 387 return VolumeMap()[volumePtr]; // Volume is already processed 530 } << 388 } 531 << 389 532 G4VSolid* solidPtr = volumePtr->GetSolid(); << 390 G4VSolid* solidPtr = volumePtr->GetSolid(); 533 G4Transform3D R, invR; << 391 G4Transform3D R,invR; 534 G4int trans = 0; << 392 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 393 620 for(std::size_t i = 0; i < daughterCount; ++ << 394 std::map<const G4LogicalVolume*, G4GDMLAuxListType>::iterator auxiter; 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 395 638 if(const G4PVDivision* const divisionvol = << 396 while (true) // Solve possible displacement/reflection 639 dynamic_cast<const G4PVDivision*>(phy << 397 { // of the referenced solid! 640 { << 398 if (trans>maxTransforms) 641 if(!G4Transform3D::Identity.isNear(invR << 642 { 399 { 643 G4String ErrorMessage = "Division volu << 400 G4String ErrorMessage = "Referenced solid in volume '" 644 "' can not be << 401 + volumePtr->GetName() >> 402 + "' was displaced/reflected too many times!"; 645 G4Exception("G4GDMLWriteStructure::Tra 403 G4Exception("G4GDMLWriteStructure::TraverseVolumeTree()", 646 "InvalidSetup", FatalExcep 404 "InvalidSetup", FatalException, ErrorMessage); 647 } 405 } 648 DivisionvolWrite(volumeElement, division << 406 649 } << 407 if (G4ReflectedSolid* refl = dynamic_cast<G4ReflectedSolid*>(solidPtr)) 650 else << 651 { << 652 if(physvol->IsParameterised()) // Is it << 653 { 408 { 654 if(!G4Transform3D::Identity.isNear(inv << 409 R = R*refl->GetTransform3D(); 655 kRe << 410 solidPtr = refl->GetConstituentMovedSolid(); 656 { << 411 trans++; 657 G4String ErrorMessage = "Parameteris << 412 continue; 658 "' can not b << 659 G4Exception("G4GDMLWriteStructure::T << 660 "InvalidSetup", FatalExc << 661 } << 662 ParamvolWrite(volumeElement, physvol); << 663 } 413 } 664 else << 414 >> 415 if (G4DisplacedSolid* disp = dynamic_cast<G4DisplacedSolid*>(solidPtr)) 665 { 416 { 666 if(physvol->IsReplicated()) // Is it << 417 R = R*G4Transform3D(disp->GetObjectRotation(), 667 { << 418 disp->GetObjectTranslation()); 668 if(!G4Transform3D::Identity.isNear(i << 419 solidPtr = disp->GetConstituentMovedSolid(); 669 k << 420 trans++; 670 { << 421 continue; 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 } 422 } 781 } << 782 // BorderSurfaceCache(GetBorderSurface(phy << 783 GetBorderSurface(physvol); << 784 } << 785 423 786 if(cexport) << 424 break; 787 { << 425 } 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 426 825 // ------------------------------------------- << 427 //check if it is a reflected volume 826 void G4GDMLWriteStructure::AddVolumeAuxiliary( << 428 G4LogicalVolume* tmplv = const_cast<G4LogicalVolume*>(volumePtr); 827 << 429 >> 430 if (reflFactory->IsReflected(tmplv)) >> 431 { >> 432 tmplv = reflFactory->GetConstituentLV(tmplv); >> 433 if (VolumeMap().find(tmplv) != VolumeMap().end()) >> 434 { >> 435 return R; // Volume is already processed >> 436 } >> 437 } >> 438 >> 439 // Only compute the inverse when necessary! >> 440 // >> 441 if (trans>0) { invR = R.inverse(); } >> 442 >> 443 const G4String name >> 444 = GenerateName(tmplv->GetName(), tmplv); >> 445 const G4String materialref >> 446 = GenerateName(volumePtr->GetMaterial()->GetName(), >> 447 volumePtr->GetMaterial()); >> 448 const G4String solidref >> 449 = GenerateName(solidPtr->GetName(),solidPtr); >> 450 >> 451 xercesc::DOMElement* volumeElement = NewElement("volume"); >> 452 volumeElement->setAttributeNode(NewAttribute("name",name)); >> 453 xercesc::DOMElement* materialrefElement = NewElement("materialref"); >> 454 materialrefElement->setAttributeNode(NewAttribute("ref",materialref)); >> 455 volumeElement->appendChild(materialrefElement); >> 456 xercesc::DOMElement* solidrefElement = NewElement("solidref"); >> 457 solidrefElement->setAttributeNode(NewAttribute("ref",solidref)); >> 458 volumeElement->appendChild(solidrefElement); >> 459 >> 460 const G4int daughterCount = volumePtr->GetNoDaughters(); >> 461 >> 462 for (G4int i=0;i<daughterCount;i++) // Traverse all the children! >> 463 { >> 464 const G4VPhysicalVolume* const physvol = volumePtr->GetDaughter(i); >> 465 const G4String ModuleName = Modularize(physvol,depth); >> 466 >> 467 G4Transform3D daughterR; >> 468 >> 469 if (ModuleName.empty()) // Check if subtree requested to be >> 470 { // a separate module! >> 471 daughterR = TraverseVolumeTree(physvol->GetLogicalVolume(),depth+1); >> 472 } >> 473 else >> 474 { >> 475 G4GDMLWriteStructure writer; >> 476 daughterR = writer.Write(ModuleName,physvol->GetLogicalVolume(), >> 477 SchemaLocation,depth+1); >> 478 } >> 479 >> 480 if (const G4PVDivision* const divisionvol >> 481 = dynamic_cast<const G4PVDivision*>(physvol)) // Is it division? >> 482 { >> 483 if (!G4Transform3D::Identity.isNear(invR*daughterR,kRelativePrecision)) >> 484 { >> 485 G4String ErrorMessage = "Division volume in '" + name >> 486 + "' can not be related to reflected solid!"; >> 487 G4Exception("G4GDMLWriteStructure::TraverseVolumeTree()", >> 488 "InvalidSetup", FatalException, ErrorMessage); >> 489 } >> 490 DivisionvolWrite(volumeElement,divisionvol); >> 491 } else >> 492 if (physvol->IsParameterised()) // Is it a paramvol? >> 493 { >> 494 if (!G4Transform3D::Identity.isNear(invR*daughterR,kRelativePrecision)) >> 495 { >> 496 G4String ErrorMessage = "Parameterised volume in '" + name >> 497 + "' can not be related to reflected solid!"; >> 498 G4Exception("G4GDMLWriteStructure::TraverseVolumeTree()", >> 499 "InvalidSetup", FatalException, ErrorMessage); >> 500 } >> 501 ParamvolWrite(volumeElement,physvol); >> 502 } else >> 503 if (physvol->IsReplicated()) // Is it a replicavol? >> 504 { >> 505 if (!G4Transform3D::Identity.isNear(invR*daughterR,kRelativePrecision)) >> 506 { >> 507 G4String ErrorMessage = "Replica volume in '" + name >> 508 + "' can not be related to reflected solid!"; >> 509 G4Exception("G4GDMLWriteStructure::TraverseVolumeTree()", >> 510 "InvalidSetup", FatalException, ErrorMessage); >> 511 } >> 512 ReplicavolWrite(volumeElement,physvol); >> 513 } >> 514 else // Is it a physvol? >> 515 { >> 516 G4RotationMatrix rot; >> 517 if (physvol->GetFrameRotation() != 0) >> 518 { >> 519 rot = *(physvol->GetFrameRotation()); >> 520 } >> 521 G4Transform3D P(rot,physvol->GetObjectTranslation()); >> 522 >> 523 PhysvolWrite(volumeElement,physvol,invR*P*daughterR,ModuleName); >> 524 } >> 525 BorderSurfaceCache(GetBorderSurface(physvol)); >> 526 } >> 527 >> 528 if (cexport) { ExportEnergyCuts(volumePtr); } >> 529 // Add optional energy cuts >> 530 >> 531 // Here write the auxiliary info >> 532 // >> 533 auxiter = auxmap.find(volumePtr); >> 534 if (auxiter != auxmap.end()) >> 535 { >> 536 AddAuxInfo(&(auxiter->second), volumeElement); >> 537 } >> 538 >> 539 structureElement->appendChild(volumeElement); >> 540 // Append the volume AFTER traversing the children so that >> 541 // the order of volumes will be correct! >> 542 >> 543 VolumeMap()[tmplv] = R; >> 544 >> 545 AddExtension(volumeElement, volumePtr); >> 546 // Add any possible user defined extension attached to a volume >> 547 >> 548 AddMaterial(volumePtr->GetMaterial()); >> 549 // Add the involved materials and solids! >> 550 >> 551 AddSolid(solidPtr); >> 552 >> 553 SkinSurfaceCache(GetSkinSurface(volumePtr)); >> 554 >> 555 return R; >> 556 } >> 557 >> 558 void >> 559 G4GDMLWriteStructure::AddVolumeAuxiliary(G4GDMLAuxStructType myaux, >> 560 const G4LogicalVolume* const lvol) 828 { 561 { 829 auto pos = auxmap.find(lvol); << 562 std::map<const G4LogicalVolume*, 830 << 563 G4GDMLAuxListType>::iterator pos = auxmap.find(lvol); 831 if(pos == auxmap.cend()) << 832 { << 833 auxmap[lvol] = G4GDMLAuxListType(); << 834 } << 835 564 >> 565 if (pos == auxmap.end()) { auxmap[lvol] = G4GDMLAuxListType(); } >> 566 836 auxmap[lvol].push_back(myaux); 567 auxmap[lvol].push_back(myaux); 837 } 568 } 838 569 839 // ------------------------------------------- << 570 void 840 void G4GDMLWriteStructure::SetEnergyCutsExport << 571 G4GDMLWriteStructure::SetEnergyCutsExport(G4bool fcuts) 841 { 572 { 842 cexport = fcuts; 573 cexport = fcuts; 843 } 574 } 844 575 845 // ------------------------------------------- << 576 void 846 void G4GDMLWriteStructure::ExportEnergyCuts(co << 577 G4GDMLWriteStructure::ExportEnergyCuts(const G4LogicalVolume* const lvol) 847 { 578 { 848 G4GDMLEvaluator eval; 579 G4GDMLEvaluator eval; 849 G4ProductionCuts* pcuts = lvol->GetRegio << 580 G4ProductionCuts* pcuts = lvol->GetRegion()->GetProductionCuts(); 850 G4ProductionCutsTable* ctab = G4ProductionCu 581 G4ProductionCutsTable* ctab = G4ProductionCutsTable::GetProductionCutsTable(); 851 G4Gamma* gamma = G4Gamma::Gamma << 582 G4Gamma* gamma = G4Gamma::Gamma(); 852 G4Electron* eminus = G4Electron::El << 583 G4Electron* eminus = G4Electron::Electron(); 853 G4Positron* eplus = G4Positron::Po << 584 G4Positron* eplus = G4Positron::Positron(); 854 G4Proton* proton = G4Proton::Prot << 585 G4Proton* proton = G4Proton::Proton(); 855 << 586 856 G4double gamma_cut = ctab->ConvertRangeToEne << 587 G4double gamma_cut = ctab->ConvertRangeToEnergy(gamma, lvol->GetMaterial(), 857 gamma, lvol->GetMaterial(), pcuts->GetProd << 588 pcuts->GetProductionCut("gamma")); 858 G4double eminus_cut = ctab->ConvertRangeToEn << 589 G4double eminus_cut = ctab->ConvertRangeToEnergy(eminus, lvol->GetMaterial(), 859 eminus, lvol->GetMaterial(), pcuts->GetPro << 590 pcuts->GetProductionCut("e-")); 860 G4double eplus_cut = ctab->ConvertRangeToEne << 591 G4double eplus_cut = ctab->ConvertRangeToEnergy(eplus, lvol->GetMaterial(), 861 eplus, lvol->GetMaterial(), pcuts->GetProd << 592 pcuts->GetProductionCut("e+")); 862 G4double proton_cut = ctab->ConvertRangeToEn << 593 G4double proton_cut = ctab->ConvertRangeToEnergy(proton, lvol->GetMaterial(), 863 proton, lvol->GetMaterial(), pcuts->GetPro << 594 pcuts->GetProductionCut("proton")); 864 << 595 865 G4GDMLAuxStructType gammainfo = { "gammaECu << 596 G4GDMLAuxStructType gammainfo = {"gammaECut", 866 eval.Conve << 597 eval.ConvertToString(gamma_cut), "MeV", 0}; 867 G4GDMLAuxStructType eminusinfo = { "electron << 598 G4GDMLAuxStructType eminusinfo = {"electronECut", 868 eval.Conv << 599 eval.ConvertToString(eminus_cut), "MeV", 0}; 869 0 }; << 600 G4GDMLAuxStructType eplusinfo = {"positronECut", 870 G4GDMLAuxStructType eplusinfo = { "positron << 601 eval.ConvertToString(eplus_cut), "MeV", 0}; 871 eval.Conve << 602 G4GDMLAuxStructType protinfo = {"protonECut", 872 G4GDMLAuxStructType protinfo = { "protonEC << 603 eval.ConvertToString(proton_cut), "MeV", 0}; 873 eval.Conver << 874 604 875 AddVolumeAuxiliary(gammainfo, lvol); 605 AddVolumeAuxiliary(gammainfo, lvol); 876 AddVolumeAuxiliary(eminusinfo, lvol); 606 AddVolumeAuxiliary(eminusinfo, lvol); 877 AddVolumeAuxiliary(eplusinfo, lvol); 607 AddVolumeAuxiliary(eplusinfo, lvol); 878 AddVolumeAuxiliary(protinfo, lvol); 608 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 } 609 } 919 610