22#include "G4OpticalSurface.hh"
23#include "G4LogicalSkinSurface.hh"
24#include "G4LogicalBorderSurface.hh"
28const std::unordered_map<std::string, G4SurfaceType>& surfaceTypesMap() {
29 static const std::unordered_map<std::string, G4SurfaceType> types = {
30 {
"dielectric_metal", dielectric_metal},
31 {
"dielectric_dielectric", dielectric_dielectric},
32 {
"dielectric_LUT", dielectric_LUT},
33 {
"dielectric_LUTDAVIS", dielectric_LUTDAVIS},
34 {
"dielectric_dichroic", dielectric_dichroic},
41const std::unordered_map<std::string, G4OpticalSurfaceFinish>& surfaceFinishesMap() {
42 static const std::unordered_map<std::string, G4OpticalSurfaceFinish> finishes = {
43 {
"polished", polished},
44 {
"polishedfrontpainted", polishedfrontpainted},
45 {
"polishedbackpainted", polishedbackpainted},
47 {
"groundfrontpainted", groundfrontpainted},
48 {
"groundbackpainted", groundbackpainted},
50 {
"polishedlumirrorair", polishedlumirrorair},
51 {
"polishedlumirrorglue", polishedlumirrorglue},
52 {
"polishedair", polishedair},
53 {
"polishedteflonair", polishedteflonair},
54 {
"polishedtioair", polishedtioair},
55 {
"polishedtyvekair", polishedtyvekair},
56 {
"polishedvm2000air", polishedvm2000air},
57 {
"polishedvm2000glue", polishedvm2000glue},
58 {
"etchedlumirrorair", etchedlumirrorair},
59 {
"etchedlumirrorglue", etchedlumirrorglue},
60 {
"etchedair", etchedair},
61 {
"etchedteflonair", etchedteflonair},
62 {
"etchedtioair", etchedtioair},
63 {
"etchedtyvekair", etchedtyvekair},
64 {
"etchedvm2000air", etchedvm2000air},
65 {
"etchedvm2000glue", etchedvm2000glue},
66 {
"groundlumirrorair", groundlumirrorair},
67 {
"groundlumirrorglue", groundlumirrorglue},
68 {
"groundair", groundair},
69 {
"groundteflonair", groundteflonair},
70 {
"groundtioair", groundtioair},
71 {
"groundtyvekair", groundtyvekair},
72 {
"groundvm2000air", groundvm2000air},
73 {
"groundvm2000glue", groundvm2000glue},
75 {
"Rough_LUT", Rough_LUT},
76 {
"RoughTeflon_LUT", RoughTeflon_LUT},
77 {
"RoughESR_LUT", RoughESR_LUT},
78 {
"RoughESRGrease_LUT", RoughESRGrease_LUT},
79 {
"Polished_LUT", Polished_LUT},
80 {
"PolishedTeflon_LUT", PolishedTeflon_LUT},
81 {
"PolishedESR_LUT", PolishedESR_LUT},
82 {
"PolishedESRGrease_LUT", PolishedESRGrease_LUT},
83 {
"Detector_LUT", Detector_LUT}
88const std::unordered_map<std::string, G4OpticalSurfaceModel>& surfaceModelsMap() {
89 static const std::unordered_map<std::string, G4OpticalSurfaceModel> models = {
94 {
"dichroic", dichroic}
102void G4World::buildOpticalSurfaces(
SystemMap* system_map) {
103 int nSkinSurfaces = 0;
104 int nBorderSurfaces = 0;
106 for (
auto& [systemName,
gsystem] : *system_map) {
107 for (
auto& [volumeName, gvolumePtr] :
gsystem->getGVolumesMap()) {
108 auto* gvolume = gvolumePtr.get();
110 std::string mirrorName = gvolume->getMirror();
111 if (
gutilities::is_unset(mirrorName) || mirrorName ==
"no" || mirrorName ==
"none") {
continue; }
114 if (!gvolume->getExistence()) {
continue; }
117 if (gmirror ==
nullptr) {
119 volumeName,
"> is not defined in system <", systemName,
">");
122 G4OpticalSurface* surface = getOrCreateOpticalSurface(systemName, gmirror);
125 if (g4volume ==
nullptr) {
127 "> referencing mirror <", mirrorName,
"> was not built");
132 new G4LogicalSkinSurface(gvolume->getG4Name(), g4volume->
getLogical(), surface);
134 log->
info(2,
"G4World: skin surface <", systemName, GSYSTEM_DELIMITER, mirrorName,
135 "> attached to volume <", gvolume->getG4Name(),
">");
142 if (borderG4Volume ==
nullptr || borderG4Volume->
getPhysical() ==
nullptr) {
144 "> of mirror <", mirrorName,
"> referenced by volume <",
145 volumeName,
"> is not built");
147 std::string surfaceName = gvolume->getG4Name() +
"_to_" + borderG4Name;
148 new G4LogicalBorderSurface(surfaceName, g4volume->
getPhysical(),
151 log->
info(2,
"G4World: border surface <", surfaceName,
"> using mirror <",
152 systemName, GSYSTEM_DELIMITER, mirrorName,
">");
157 if (nSkinSurfaces + nBorderSurfaces > 0) {
158 log->
info(1,
"G4World: created ", g4opticalSurfacesMap.size(),
" optical surfaces, attached to ",
159 nSkinSurfaces,
" skin and ", nBorderSurfaces,
" border logical surfaces");
164G4OpticalSurface* G4World::getOrCreateOpticalSurface(
const std::string& systemName,
const GMirror* gmirror) {
167 auto cached = g4opticalSurfacesMap.find(surfaceKey);
168 if (cached != g4opticalSurfacesMap.end()) {
return cached->second; }
170 auto* surface =
new G4OpticalSurface(surfaceKey);
173 auto typeIt = surfaceTypesMap().find(gmirror->
getType());
174 if (typeIt == surfaceTypesMap().end()) {
176 ">: unknown surface type <", gmirror->
getType(),
">");
178 surface->SetType(typeIt->second);
180 auto finishIt = surfaceFinishesMap().find(gmirror->
getFinish());
181 if (finishIt == surfaceFinishesMap().end()) {
183 ">: unknown surface finish <", gmirror->
getFinish(),
">");
185 surface->SetFinish(finishIt->second);
187 auto modelIt = surfaceModelsMap().find(gmirror->
getModel());
188 if (modelIt == surfaceModelsMap().end()) {
190 ">: unknown surface model <", gmirror->
getModel(),
">");
192 surface->SetModel(modelIt->second);
201 G4Material* material =
nullptr;
203 auto matIt = g4materialsMap.find(materialName);
204 if (matIt != g4materialsMap.end()) { material = matIt->second; }
205 else { material = G4NistManager::Instance()->FindMaterial(materialName); }
207 if (material ==
nullptr) {
209 ">: matOptProps material <", materialName,
"> not found");
211 if (material->GetMaterialPropertiesTable() ==
nullptr) {
213 ">: matOptProps material <", materialName,
"> has no material properties table");
215 surface->SetMaterialPropertiesTable(material->GetMaterialPropertiesTable());
218 auto* mpt =
new G4MaterialPropertiesTable();
221 auto addProperty = [&](
const char* propertyName,
const std::vector<double>& values) {
222 if (values.empty()) {
return; }
223 mpt->AddProperty(propertyName, photonEnergy, values);
234 surface->SetMaterialPropertiesTable(mpt);
237 g4opticalSurfacesMap[surfaceKey] = surface;
238 log->
info(1,
"G4World: created optical surface <", surfaceKey,
"> type <", gmirror->
getType(),
Convenience container holding a Geant4 solid, logical, and physical volume.
G4VPhysicalVolume * getPhysical() const noexcept
Return the stored G4VPhysicalVolume pointer.
G4LogicalVolume * getLogical() const noexcept
Return the stored G4LogicalVolume pointer.
const G4Volume * getG4Volume(const std::string &volumeName) const
Return the G4Volume wrapper for a volume name.
std::shared_ptr< GLogger > log
void info(int level, Args &&... args) const
void error(int exit_code, Args &&... args) const
std::vector< double > getReflectivity() const
std::vector< double > getSpecularSpike() const
std::vector< double > getEfficiency() const
bool hasSigmaAlpha() const
std::string getName() const
std::vector< double > getPhotonEnergy() const
std::string getMatOptProps() const
bool usesMaterialOpticalProperties() const
std::vector< double > getBackscatter() const
std::vector< double > getTransmittance() const
double getSigmaAlpha() const
std::string getType() const
std::vector< double > getSpecularLobe() const
std::string getFinish() const
std::string getBorder() const
std::string getModel() const
bool isSkinSurface() const
std::vector< double > getIndexOfRefraction() const
Conventions, labels, and error codes used by the g4system geometry/material layer.
#define ERR_G4VOLUMEBUILDFAILED
A volume could not be fully built (solid/logical/physical).
#define ERR_G4MATERIALNOTFOUND
Material lookup failed and no fallback was available.
#define ERR_G4MIRRORNOTFOUND
A volume references a mirror that is not defined in its system.
#define ERR_G4SURFACECONFIGINVALID
Optical surface type/finish/model/properties are invalid.
High-level builder that turns a GEMC world description into Geant4 geometry.
#define GSYSTEM_DELIMITER
std::map< std::string, SystemPtr > SystemMap
bool is_unset(std::string_view s)