File indexing completed on 2025-08-05 08:18:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #include "PHG4GDMLWriteStructure.hh"
0036 #include "PHG4GDMLConfig.hh"
0037
0038 #include <Geant4/G4DisplacedSolid.hh>
0039 #include <Geant4/G4LogicalBorderSurface.hh>
0040 #include <Geant4/G4LogicalSkinSurface.hh>
0041 #include <Geant4/G4LogicalVolumeStore.hh>
0042 #include <Geant4/G4Material.hh>
0043 #include <Geant4/G4OpticalSurface.hh>
0044 #include <Geant4/G4PVDivision.hh>
0045 #include <Geant4/G4PVReplica.hh>
0046 #include <Geant4/G4PhysicalVolumeStore.hh>
0047 #include <Geant4/G4ReflectedSolid.hh>
0048 #include <Geant4/G4ReflectionFactory.hh>
0049 #include <Geant4/G4Region.hh>
0050
0051 #include <Geant4/G4Electron.hh>
0052 #include <Geant4/G4Gamma.hh>
0053 #include <Geant4/G4Positron.hh>
0054 #include <Geant4/G4ProductionCuts.hh>
0055 #include <Geant4/G4ProductionCutsTable.hh>
0056 #include <Geant4/G4Proton.hh>
0057 #include <Geant4/G4Version.hh>
0058
0059 #include <cassert>
0060
0061 PHG4GDMLWriteStructure::PHG4GDMLWriteStructure(const PHG4GDMLConfig* config_input)
0062 : PHG4GDMLWriteParamvol()
0063 , structureElement(nullptr)
0064 , cexport(false)
0065 , config(config_input)
0066 {
0067 assert(config);
0068 reflFactory = G4ReflectionFactory::Instance();
0069 }
0070
0071 PHG4GDMLWriteStructure::~PHG4GDMLWriteStructure()
0072 {
0073 }
0074
0075 void PHG4GDMLWriteStructure::DivisionvolWrite(xercesc::DOMElement* volumeElement,
0076 const G4PVDivision* const divisionvol)
0077 {
0078 EAxis axis = kUndefined;
0079 G4int number = 0;
0080 G4double width = 0.0;
0081 G4double offset = 0.0;
0082 G4bool consuming = false;
0083
0084 divisionvol->GetReplicationData(axis, number, width, offset, consuming);
0085 axis = divisionvol->GetDivisionAxis();
0086
0087 G4String unitString("mm");
0088 G4String axisString("kUndefined");
0089 if (axis == kXAxis)
0090 {
0091 axisString = "kXAxis";
0092 }
0093 else if (axis == kYAxis)
0094 {
0095 axisString = "kYAxis";
0096 }
0097 else if (axis == kZAxis)
0098 {
0099 axisString = "kZAxis";
0100 }
0101 else if (axis == kRho)
0102 {
0103 axisString = "kRho";
0104 }
0105 else if (axis == kPhi)
0106 {
0107 axisString = "kPhi";
0108 unitString = "rad";
0109 }
0110
0111 const G4String name = GenerateName(divisionvol->GetName(), divisionvol);
0112 const G4String volumeref = GenerateName(divisionvol->GetLogicalVolume()->GetName(),
0113 divisionvol->GetLogicalVolume());
0114
0115 xercesc::DOMElement* divisionvolElement = NewElement("divisionvol");
0116 divisionvolElement->setAttributeNode(NewAttribute("axis", axisString));
0117 divisionvolElement->setAttributeNode(NewAttribute("number", number));
0118 divisionvolElement->setAttributeNode(NewAttribute("width", width));
0119 divisionvolElement->setAttributeNode(NewAttribute("offset", offset));
0120 divisionvolElement->setAttributeNode(NewAttribute("unit", unitString));
0121 xercesc::DOMElement* volumerefElement = NewElement("volumeref");
0122 volumerefElement->setAttributeNode(NewAttribute("ref", volumeref));
0123 divisionvolElement->appendChild(volumerefElement);
0124 volumeElement->appendChild(divisionvolElement);
0125 }
0126
0127 void PHG4GDMLWriteStructure::PhysvolWrite(xercesc::DOMElement* volumeElement,
0128 const G4VPhysicalVolume* const physvol,
0129 const G4Transform3D& T,
0130 const G4String& ModuleName)
0131 {
0132 HepGeom::Scale3D scale;
0133 HepGeom::Rotate3D rotate;
0134 HepGeom::Translate3D translate;
0135
0136 T.getDecomposition(scale, rotate, translate);
0137
0138 const G4ThreeVector scl(scale(0, 0), scale(1, 1), scale(2, 2));
0139 const G4ThreeVector rot = GetAngles(rotate.getRotation());
0140 const G4ThreeVector pos = T.getTranslation();
0141
0142 const G4String name = GenerateName(physvol->GetName(), physvol);
0143 const G4int copynumber = physvol->GetCopyNo();
0144
0145 xercesc::DOMElement* physvolElement = NewElement("physvol");
0146 physvolElement->setAttributeNode(NewAttribute("name", name));
0147 if (copynumber) physvolElement->setAttributeNode(NewAttribute("copynumber", copynumber));
0148
0149 volumeElement->appendChild(physvolElement);
0150
0151 G4LogicalVolume* lv;
0152
0153 if (reflFactory->IsReflected(physvol->GetLogicalVolume()))
0154 {
0155 lv = reflFactory->GetConstituentLV(physvol->GetLogicalVolume());
0156 }
0157 else
0158 {
0159 lv = physvol->GetLogicalVolume();
0160 }
0161
0162 const G4String volumeref = GenerateName(lv->GetName(), lv);
0163
0164 if (ModuleName.empty())
0165 {
0166 xercesc::DOMElement* volumerefElement = NewElement("volumeref");
0167 volumerefElement->setAttributeNode(NewAttribute("ref", volumeref));
0168 physvolElement->appendChild(volumerefElement);
0169 }
0170 else
0171 {
0172 xercesc::DOMElement* fileElement = NewElement("file");
0173 fileElement->setAttributeNode(NewAttribute("name", ModuleName));
0174 fileElement->setAttributeNode(NewAttribute("volname", volumeref));
0175 physvolElement->appendChild(fileElement);
0176 }
0177
0178 if (std::fabs(pos.x()) > kLinearPrecision || std::fabs(pos.y()) > kLinearPrecision || std::fabs(pos.z()) > kLinearPrecision)
0179 {
0180 PositionWrite(physvolElement, name + "_pos", pos);
0181 }
0182 if (std::fabs(rot.x()) > kAngularPrecision || std::fabs(rot.y()) > kAngularPrecision || std::fabs(rot.z()) > kAngularPrecision)
0183 {
0184 RotationWrite(physvolElement, name + "_rot", rot);
0185 }
0186 if (std::fabs(scl.x() - 1.0) > kRelativePrecision || std::fabs(scl.y() - 1.0) > kRelativePrecision || std::fabs(scl.z() - 1.0) > kRelativePrecision)
0187 {
0188 ScaleWrite(physvolElement, name + "_scl", scl);
0189 }
0190 }
0191
0192 void PHG4GDMLWriteStructure::ReplicavolWrite(xercesc::DOMElement* volumeElement,
0193 const G4VPhysicalVolume* const replicavol)
0194 {
0195 EAxis axis = kUndefined;
0196 G4int number = 0;
0197 G4double width = 0.0;
0198 G4double offset = 0.0;
0199 G4bool consuming = false;
0200 G4String unitString("mm");
0201
0202 replicavol->GetReplicationData(axis, number, width, offset, consuming);
0203
0204 const G4String volumeref = GenerateName(replicavol->GetLogicalVolume()->GetName(),
0205 replicavol->GetLogicalVolume());
0206
0207 xercesc::DOMElement* replicavolElement = NewElement("replicavol");
0208 replicavolElement->setAttributeNode(NewAttribute("number", number));
0209 xercesc::DOMElement* volumerefElement = NewElement("volumeref");
0210 volumerefElement->setAttributeNode(NewAttribute("ref", volumeref));
0211 replicavolElement->appendChild(volumerefElement);
0212 xercesc::DOMElement* replicateElement = NewElement("replicate_along_axis");
0213 replicavolElement->appendChild(replicateElement);
0214
0215 xercesc::DOMElement* dirElement = NewElement("direction");
0216 if (axis == kXAxis)
0217 {
0218 dirElement->setAttributeNode(NewAttribute("x", "1"));
0219 }
0220 else if (axis == kYAxis)
0221 {
0222 dirElement->setAttributeNode(NewAttribute("y", "1"));
0223 }
0224 else if (axis == kZAxis)
0225 {
0226 dirElement->setAttributeNode(NewAttribute("z", "1"));
0227 }
0228 else if (axis == kRho)
0229 {
0230 dirElement->setAttributeNode(NewAttribute("rho", "1"));
0231 }
0232 else if (axis == kPhi)
0233 {
0234 dirElement->setAttributeNode(NewAttribute("phi", "1"));
0235 unitString = "rad";
0236 }
0237 replicateElement->appendChild(dirElement);
0238
0239 xercesc::DOMElement* widthElement = NewElement("width");
0240 widthElement->setAttributeNode(NewAttribute("value", width));
0241 widthElement->setAttributeNode(NewAttribute("unit", unitString));
0242 replicateElement->appendChild(widthElement);
0243
0244 xercesc::DOMElement* offsetElement = NewElement("offset");
0245 offsetElement->setAttributeNode(NewAttribute("value", offset));
0246 offsetElement->setAttributeNode(NewAttribute("unit", unitString));
0247 replicateElement->appendChild(offsetElement);
0248
0249 volumeElement->appendChild(replicavolElement);
0250 }
0251
0252 void PHG4GDMLWriteStructure::
0253 BorderSurfaceCache(const G4LogicalBorderSurface* const bsurf)
0254 {
0255 if (!bsurf)
0256 {
0257 return;
0258 }
0259
0260 const G4SurfaceProperty* psurf = bsurf->GetSurfaceProperty();
0261
0262
0263
0264 xercesc::DOMElement* borderElement = NewElement("bordersurface");
0265 borderElement->setAttributeNode(NewAttribute("name", bsurf->GetName()));
0266 borderElement->setAttributeNode(NewAttribute("surfaceproperty",
0267 psurf->GetName()));
0268
0269 const G4String volumeref1 = GenerateName(bsurf->GetVolume1()->GetName(),
0270 bsurf->GetVolume1());
0271 const G4String volumeref2 = GenerateName(bsurf->GetVolume2()->GetName(),
0272 bsurf->GetVolume2());
0273 xercesc::DOMElement* volumerefElement1 = NewElement("physvolref");
0274 xercesc::DOMElement* volumerefElement2 = NewElement("physvolref");
0275 volumerefElement1->setAttributeNode(NewAttribute("ref", volumeref1));
0276 volumerefElement2->setAttributeNode(NewAttribute("ref", volumeref2));
0277 borderElement->appendChild(volumerefElement1);
0278 borderElement->appendChild(volumerefElement2);
0279
0280 if (FindOpticalSurface(psurf))
0281 {
0282 const G4OpticalSurface* opsurf =
0283 dynamic_cast<const G4OpticalSurface*>(psurf);
0284 if (!opsurf)
0285 {
0286 G4Exception("PHG4GDMLWriteStructure::BorderSurfaceCache()",
0287 "InvalidSetup", FatalException, "No optical surface found!");
0288 return;
0289 }
0290 OpticalSurfaceWrite(solidsElement, opsurf);
0291 }
0292
0293 borderElementVec.push_back(borderElement);
0294 }
0295
0296 void PHG4GDMLWriteStructure::
0297 SkinSurfaceCache(const G4LogicalSkinSurface* const ssurf)
0298 {
0299 if (!ssurf)
0300 {
0301 return;
0302 }
0303
0304 const G4SurfaceProperty* psurf = ssurf->GetSurfaceProperty();
0305
0306
0307
0308 xercesc::DOMElement* skinElement = NewElement("skinsurface");
0309 skinElement->setAttributeNode(NewAttribute("name", ssurf->GetName()));
0310 skinElement->setAttributeNode(NewAttribute("surfaceproperty",
0311 psurf->GetName()));
0312
0313 const G4String volumeref = GenerateName(ssurf->GetLogicalVolume()->GetName(),
0314 ssurf->GetLogicalVolume());
0315 xercesc::DOMElement* volumerefElement = NewElement("volumeref");
0316 volumerefElement->setAttributeNode(NewAttribute("ref", volumeref));
0317 skinElement->appendChild(volumerefElement);
0318
0319 if (FindOpticalSurface(psurf))
0320 {
0321 const G4OpticalSurface* opsurf =
0322 dynamic_cast<const G4OpticalSurface*>(psurf);
0323 if (!opsurf)
0324 {
0325 G4Exception("PHG4GDMLWriteStructure::SkinSurfaceCache()",
0326 "InvalidSetup", FatalException, "No optical surface found!");
0327 return;
0328 }
0329 OpticalSurfaceWrite(solidsElement, opsurf);
0330 }
0331
0332 skinElementVec.push_back(skinElement);
0333 }
0334
0335 G4bool PHG4GDMLWriteStructure::FindOpticalSurface(const G4SurfaceProperty* psurf)
0336 {
0337 const G4OpticalSurface* osurf = dynamic_cast<const G4OpticalSurface*>(psurf);
0338 std::vector<const G4OpticalSurface*>::const_iterator pos;
0339 pos = std::find(opt_vec.begin(), opt_vec.end(), osurf);
0340 if (pos != opt_vec.end())
0341 {
0342 return false;
0343 }
0344
0345 opt_vec.push_back(osurf);
0346 return true;
0347 }
0348
0349 const G4LogicalSkinSurface*
0350 PHG4GDMLWriteStructure::GetSkinSurface(const G4LogicalVolume* const lvol)
0351 {
0352 G4LogicalSkinSurface* surf = 0;
0353 G4int nsurf = G4LogicalSkinSurface::GetNumberOfSkinSurfaces();
0354 if (nsurf)
0355 {
0356 const G4LogicalSkinSurfaceTable* stable =
0357 G4LogicalSkinSurface::GetSurfaceTable();
0358 std::vector<G4LogicalSkinSurface*>::const_iterator pos;
0359 for (pos = stable->begin(); pos != stable->end(); ++pos)
0360 {
0361 if (lvol == (*pos)->GetLogicalVolume())
0362 {
0363 surf = *pos;
0364 break;
0365 }
0366 }
0367 }
0368 return surf;
0369 }
0370
0371 #if G4VERSION_NUMBER >= 1007
0372
0373 const G4LogicalBorderSurface* PHG4GDMLWriteStructure::GetBorderSurface(
0374 const G4VPhysicalVolume* const pvol)
0375 {
0376 G4LogicalBorderSurface* surf = nullptr;
0377 G4int nsurf = G4LogicalBorderSurface::GetNumberOfBorderSurfaces();
0378 if (nsurf)
0379 {
0380 const G4LogicalBorderSurfaceTable* btable =
0381 G4LogicalBorderSurface::GetSurfaceTable();
0382 for (auto pos = btable->cbegin(); pos != btable->cend(); ++pos)
0383 {
0384 if (pvol == pos->first.first)
0385 {
0386 surf = pos->second;
0387 BorderSurfaceCache(surf);
0388 }
0389 }
0390 }
0391 return surf;
0392 }
0393
0394 #else
0395
0396 const G4LogicalBorderSurface*
0397 PHG4GDMLWriteStructure::GetBorderSurface(const G4VPhysicalVolume* const pvol)
0398 {
0399 G4LogicalBorderSurface* surf = 0;
0400 G4int nsurf = G4LogicalBorderSurface::GetNumberOfBorderSurfaces();
0401 if (nsurf)
0402 {
0403 const G4LogicalBorderSurfaceTable* btable =
0404 G4LogicalBorderSurface::GetSurfaceTable();
0405 std::vector<G4LogicalBorderSurface*>::const_iterator pos;
0406 for (pos = btable->begin(); pos != btable->end(); ++pos)
0407 {
0408 if (pvol == (*pos)->GetVolume1())
0409 {
0410 surf = *pos;
0411 break;
0412 }
0413 }
0414 }
0415 return surf;
0416 }
0417
0418 #endif
0419
0420 void PHG4GDMLWriteStructure::SurfacesWrite()
0421 {
0422 std::cout << "PHG4GDML: Writing surfaces..." << std::endl;
0423
0424 std::vector<xercesc::DOMElement*>::const_iterator pos;
0425 for (pos = skinElementVec.begin(); pos != skinElementVec.end(); ++pos)
0426 {
0427 structureElement->appendChild(*pos);
0428 }
0429 for (pos = borderElementVec.begin(); pos != borderElementVec.end(); ++pos)
0430 {
0431 structureElement->appendChild(*pos);
0432 }
0433 }
0434
0435 void PHG4GDMLWriteStructure::StructureWrite(xercesc::DOMElement* gdmlElement)
0436 {
0437 std::cout << "PHG4GDML: Writing structure..." << std::endl;
0438
0439 structureElement = NewElement("structure");
0440 gdmlElement->appendChild(structureElement);
0441 }
0442
0443 G4Transform3D PHG4GDMLWriteStructure::
0444 TraverseVolumeTree(const G4LogicalVolume* const volumePtr, const G4int depth)
0445 {
0446 if (VolumeMap().find(volumePtr) != VolumeMap().end())
0447 {
0448 return VolumeMap()[volumePtr];
0449 }
0450
0451
0452 assert(config);
0453 if (config->get_excluded_logical_vol().find(volumePtr) != config->get_excluded_logical_vol().end())
0454 {
0455 return G4Transform3D::Identity;
0456 }
0457
0458 G4VSolid* solidPtr = volumePtr->GetSolid();
0459 G4Transform3D R, invR;
0460 G4int trans = 0;
0461
0462 std::map<const G4LogicalVolume*, PHG4GDMLAuxListType>::iterator auxiter;
0463
0464 while (true)
0465 {
0466 if (trans > maxTransforms)
0467 {
0468 G4String ErrorMessage = "Referenced solid in volume '" + volumePtr->GetName() + "' was displaced/reflected too many times!";
0469 G4Exception("PHG4GDMLWriteStructure::TraverseVolumeTree()",
0470 "InvalidSetup", FatalException, ErrorMessage);
0471 }
0472
0473 if (G4ReflectedSolid* refl = dynamic_cast<G4ReflectedSolid*>(solidPtr))
0474 {
0475 R = R * refl->GetTransform3D();
0476 solidPtr = refl->GetConstituentMovedSolid();
0477 trans++;
0478 continue;
0479 }
0480
0481 if (G4DisplacedSolid* disp = dynamic_cast<G4DisplacedSolid*>(solidPtr))
0482 {
0483 R = R * G4Transform3D(disp->GetObjectRotation(),
0484 disp->GetObjectTranslation());
0485 solidPtr = disp->GetConstituentMovedSolid();
0486 trans++;
0487 continue;
0488 }
0489
0490 break;
0491 }
0492
0493
0494 G4LogicalVolume* tmplv = const_cast<G4LogicalVolume*>(volumePtr);
0495
0496 if (reflFactory->IsReflected(tmplv))
0497 {
0498 tmplv = reflFactory->GetConstituentLV(tmplv);
0499 if (VolumeMap().find(tmplv) != VolumeMap().end())
0500 {
0501 return R;
0502 }
0503 }
0504
0505
0506
0507 if (trans > 0)
0508 {
0509 invR = R.inverse();
0510 }
0511
0512 const G4String name = GenerateName(tmplv->GetName(), tmplv);
0513 const G4String materialref = GenerateName(volumePtr->GetMaterial()->GetName(),
0514 volumePtr->GetMaterial());
0515 const G4String solidref = GenerateName(solidPtr->GetName(), solidPtr);
0516
0517 xercesc::DOMElement* volumeElement = NewElement("volume");
0518 volumeElement->setAttributeNode(NewAttribute("name", name));
0519 xercesc::DOMElement* materialrefElement = NewElement("materialref");
0520 materialrefElement->setAttributeNode(NewAttribute("ref", materialref));
0521 volumeElement->appendChild(materialrefElement);
0522 xercesc::DOMElement* solidrefElement = NewElement("solidref");
0523 solidrefElement->setAttributeNode(NewAttribute("ref", solidref));
0524 volumeElement->appendChild(solidrefElement);
0525
0526 const G4int daughterCount = volumePtr->GetNoDaughters();
0527
0528 for (G4int i = 0; i < daughterCount; i++)
0529 {
0530 const G4VPhysicalVolume* const physvol = volumePtr->GetDaughter(i);
0531
0532
0533 assert(config);
0534 if (config->get_excluded_physical_vol().find(physvol) != config->get_excluded_physical_vol().end())
0535 continue;
0536
0537 const G4String ModuleName = Modularize(physvol, depth);
0538
0539 G4Transform3D daughterR;
0540
0541 if (ModuleName.empty())
0542 {
0543 daughterR = TraverseVolumeTree(physvol->GetLogicalVolume(), depth + 1);
0544 }
0545 else
0546 {
0547 PHG4GDMLWriteStructure writer(config);
0548 daughterR = writer.Write(ModuleName, physvol->GetLogicalVolume(),
0549 SchemaLocation, depth + 1);
0550 }
0551
0552 if (const G4PVDivision* const divisionvol = dynamic_cast<const G4PVDivision*>(physvol))
0553 {
0554 if (!G4Transform3D::Identity.isNear(invR * daughterR, kRelativePrecision))
0555 {
0556 G4String ErrorMessage = "Division volume in '" + name + "' can not be related to reflected solid!";
0557 G4Exception("PHG4GDMLWriteStructure::TraverseVolumeTree()",
0558 "InvalidSetup", FatalException, ErrorMessage);
0559 }
0560 DivisionvolWrite(volumeElement, divisionvol);
0561 }
0562 else if (physvol->IsParameterised())
0563 {
0564 if (!G4Transform3D::Identity.isNear(invR * daughterR, kRelativePrecision))
0565 {
0566 G4String ErrorMessage = "Parameterised volume in '" + name + "' can not be related to reflected solid!";
0567 G4Exception("PHG4GDMLWriteStructure::TraverseVolumeTree()",
0568 "InvalidSetup", FatalException, ErrorMessage);
0569 }
0570 ParamvolWrite(volumeElement, physvol);
0571 }
0572 else if (physvol->IsReplicated())
0573 {
0574 if (!G4Transform3D::Identity.isNear(invR * daughterR, kRelativePrecision))
0575 {
0576 G4String ErrorMessage = "Replica volume in '" + name + "' can not be related to reflected solid!";
0577 G4Exception("PHG4GDMLWriteStructure::TraverseVolumeTree()",
0578 "InvalidSetup", FatalException, ErrorMessage);
0579 }
0580 ReplicavolWrite(volumeElement, physvol);
0581 }
0582 else
0583 {
0584 G4RotationMatrix rot;
0585 if (physvol->GetFrameRotation() != 0)
0586 {
0587 rot = *(physvol->GetFrameRotation());
0588 }
0589 G4Transform3D P(rot, physvol->GetObjectTranslation());
0590
0591 PhysvolWrite(volumeElement, physvol, invR * P * daughterR, ModuleName);
0592 }
0593 BorderSurfaceCache(GetBorderSurface(physvol));
0594 }
0595
0596 if (cexport)
0597 {
0598 ExportEnergyCuts(volumePtr);
0599 }
0600
0601
0602
0603
0604 auxiter = auxmap.find(volumePtr);
0605 if (auxiter != auxmap.end())
0606 {
0607 AddAuxInfo(&(auxiter->second), volumeElement);
0608 }
0609
0610 structureElement->appendChild(volumeElement);
0611
0612
0613
0614 VolumeMap()[tmplv] = R;
0615
0616 AddExtension(volumeElement, volumePtr);
0617
0618
0619 AddMaterial(volumePtr->GetMaterial());
0620
0621
0622 AddSolid(solidPtr);
0623
0624 SkinSurfaceCache(GetSkinSurface(volumePtr));
0625
0626 return R;
0627 }
0628
0629 void PHG4GDMLWriteStructure::AddVolumeAuxiliary(PHG4GDMLAuxStructType myaux,
0630 const G4LogicalVolume* const lvol)
0631 {
0632 std::map<const G4LogicalVolume*,
0633 PHG4GDMLAuxListType>::iterator pos = auxmap.find(lvol);
0634
0635 if (pos == auxmap.end())
0636 {
0637 auxmap[lvol] = PHG4GDMLAuxListType();
0638 }
0639
0640 auxmap[lvol].push_back(myaux);
0641 }
0642
0643 void PHG4GDMLWriteStructure::SetEnergyCutsExport(G4bool fcuts)
0644 {
0645 cexport = fcuts;
0646 }
0647
0648 void PHG4GDMLWriteStructure::ExportEnergyCuts(const G4LogicalVolume* const lvol)
0649 {
0650
0651 G4ProductionCuts* pcuts = lvol->GetRegion()->GetProductionCuts();
0652 G4ProductionCutsTable* ctab = G4ProductionCutsTable::GetProductionCutsTable();
0653 G4Gamma* gamma = G4Gamma::Gamma();
0654 G4Electron* eminus = G4Electron::Electron();
0655 G4Positron* eplus = G4Positron::Positron();
0656 G4Proton* proton = G4Proton::Proton();
0657
0658 G4double gamma_cut = ctab->ConvertRangeToEnergy(gamma, lvol->GetMaterial(),
0659 pcuts->GetProductionCut("gamma"));
0660 G4double eminus_cut = ctab->ConvertRangeToEnergy(eminus, lvol->GetMaterial(),
0661 pcuts->GetProductionCut("e-"));
0662 G4double eplus_cut = ctab->ConvertRangeToEnergy(eplus, lvol->GetMaterial(),
0663 pcuts->GetProductionCut("e+"));
0664 G4double proton_cut = ctab->ConvertRangeToEnergy(proton, lvol->GetMaterial(),
0665 pcuts->GetProductionCut("proton"));
0666
0667 PHG4GDMLAuxStructType gammainfo = {"gammaECut",
0668 ConvertToString(gamma_cut), "MeV", 0};
0669 PHG4GDMLAuxStructType eminusinfo = {"electronECut",
0670 ConvertToString(eminus_cut), "MeV", 0};
0671 PHG4GDMLAuxStructType eplusinfo = {"positronECut",
0672 ConvertToString(eplus_cut), "MeV", 0};
0673 PHG4GDMLAuxStructType protinfo = {"protonECut",
0674 ConvertToString(proton_cut), "MeV", 0};
0675
0676 AddVolumeAuxiliary(gammainfo, lvol);
0677 AddVolumeAuxiliary(eminusinfo, lvol);
0678 AddVolumeAuxiliary(eplusinfo, lvol);
0679 AddVolumeAuxiliary(protinfo, lvol);
0680 }
0681
0682 G4String PHG4GDMLWriteStructure::ConvertToString(G4double dval)
0683 {
0684 std::ostringstream os;
0685 os << dval;
0686 G4String vl = os.str();
0687 return vl;
0688 }