gsystem
Loading...
Searching...
No Matches
gmirror.cc
Go to the documentation of this file.
1
8#include "gutilities.h"
9
10// gsystem
11#include "gmirror.h"
12#include "gsystemConventions.h"
13
14// c++
15#include <sstream>
16
17namespace {
18// Unset markers: pygemc writes SQL NULLs ("NULL" once serialized); legacy GEMC2
19// sources used "none" / "notDefined".
20bool mirror_field_is_unset(const std::string& value) {
22 return gutilities::is_unset(trimmed) || trimmed == "none" || trimmed == "notDefined";
23}
24}
25
26GMirror::GMirror(const std::string& s, std::vector<std::string> pars,
27 const std::shared_ptr<GLogger>& logger) : GBase(logger),
28 system(s) {
29 if (pars.size() != GMIRRORNUMBEROFPARS) {
31 "Incorrect number of mirror parameters for ", pars[0], ". Expected ",
32 GMIRRORNUMBEROFPARS, " but we got ", pars.size());
33 }
34
35 // The parameter vector is a serialized DB/ASCII row. Parsing is positional.
36 size_t i = 0;
37
40
41 // Geant4 surface configuration: all mandatory.
43 finish = gutilities::removeAllSpacesFromString(pars[i++]);
45 border = gutilities::removeAllSpacesFromString(pars[i++]);
46
47 for (const auto& [field, value] : std::initializer_list<std::pair<const char*, const std::string&>>{
48 {"type", type}, {"finish", finish}, {"model", model}, {"border", border}}) {
49 if (mirror_field_is_unset(value)) {
50 log->error(ERR_GMIRRORINVALID, "mirror <", name, ">: mandatory field <", field, "> is not set");
51 }
52 }
53
54 // Boundary optical properties: a material name or the explicit tables below.
55 matOptProps = gutilities::removeAllSpacesFromString(pars[i++]);
56 if (mirror_field_is_unset(matOptProps)) { matOptProps.clear(); }
57
58 getMirrorPropertyFromString(pars[i++], "photonEnergy");
59 getMirrorPropertyFromString(pars[i++], "indexOfRefraction");
60 getMirrorPropertyFromString(pars[i++], "reflectivity");
61 getMirrorPropertyFromString(pars[i++], "efficiency");
62 getMirrorPropertyFromString(pars[i++], "specularlobe");
63 getMirrorPropertyFromString(pars[i++], "specularspike");
64 getMirrorPropertyFromString(pars[i++], "backscatter");
65 getMirrorPropertyFromString(pars[i++], "transmittance");
66
67 std::string sigmaAlphaPar = gutilities::removeLeadingAndTrailingSpacesFromString(pars[i++]);
68 // GEMC2 used -1 to mark an unset sigmaAlpha; treat it as unset for compatibility.
69 if (!mirror_field_is_unset(sigmaAlphaPar) && sigmaAlphaPar != "-1") {
70 try {
71 sigmaAlpha = std::stod(sigmaAlphaPar);
72 sigmaAlphaSet = true;
73 }
74 catch (const std::exception&) {
75 log->error(ERR_GMIRRORINVALID, "mirror <", name, ">: could not parse sigmaAlpha <", sigmaAlphaPar, ">");
76 }
77 }
78
79 // The boundary needs optical properties from one of the two sources.
80 if (matOptProps.empty() && photonEnergy.empty()) {
81 log->error(ERR_GMIRRORINVALID, "mirror <", name,
82 ">: no optical properties. Set matOptProps or photonEnergy with the properties tables");
83 }
84
85 // Every provided property vector must be evaluated on the photonEnergy grid.
86 for (const auto& [property, values] : std::initializer_list<std::pair<const char*, const std::vector<double>&>>{
87 {"indexOfRefraction", indexOfRefraction}, {"reflectivity", reflectivity},
88 {"efficiency", efficiency}, {"specularlobe", specularlobe},
89 {"specularspike", specularspike}, {"backscatter", backscatter},
90 {"transmittance", transmittance}}) {
91 if (!values.empty() && values.size() != photonEnergy.size()) {
92 log->error(ERR_GMIRRORINVALID, "mirror <", name, ">: property <", property, "> has ",
93 values.size(), " entries but photonEnergy has ", photonEnergy.size());
94 }
95 }
96}
97
98bool GMirror::isSkinSurface() const { return border == GMIRRORSKINSURFACE; }
99
100void GMirror::getMirrorPropertyFromString(const std::string& parameter, const std::string& propertyName) {
101 // Nothing to do if the parameter is not assigned.
102 if (mirror_field_is_unset(parameter)) { return; }
103
104 // Tokenize the string and parse each component to a numeric value with units.
105 std::stringstream parameterComponents(parameter);
106
107 while (!parameterComponents.eof()) {
108 std::string component;
109 parameterComponents >> component;
110
111 std::string trimmedComponent = gutilities::removeLeadingAndTrailingSpacesFromString(component);
112 if (trimmedComponent.empty()) { continue; }
113
114 if (propertyName == "photonEnergy") { photonEnergy.push_back(gutilities::getG4Number(trimmedComponent)); }
115 else if (propertyName == "indexOfRefraction") {
116 indexOfRefraction.push_back(gutilities::getG4Number(trimmedComponent));
117 }
118 else if (propertyName == "reflectivity") { reflectivity.push_back(gutilities::getG4Number(trimmedComponent)); }
119 else if (propertyName == "efficiency") { efficiency.push_back(gutilities::getG4Number(trimmedComponent)); }
120 else if (propertyName == "specularlobe") { specularlobe.push_back(gutilities::getG4Number(trimmedComponent)); }
121 else if (propertyName == "specularspike") {
122 specularspike.push_back(gutilities::getG4Number(trimmedComponent));
123 }
124 else if (propertyName == "backscatter") { backscatter.push_back(gutilities::getG4Number(trimmedComponent)); }
125 else if (propertyName == "transmittance") {
126 transmittance.push_back(gutilities::getG4Number(trimmedComponent));
127 }
128 }
129}
130
131std::ostream& operator<<(std::ostream& stream, const GMirror& gMir) {
132 stream << std::endl;
133 stream << " - Mirror: " << gMir.name << " in system " << gMir.system << ": " << std::endl;
134 stream << " Type / Finish / Model: " << gMir.type << " / " << gMir.finish << " / " << gMir.model << std::endl;
135 stream << " Border: " << gMir.border << std::endl;
136 if (!gMir.matOptProps.empty()) {
137 stream << " Optical properties from material: " << gMir.matOptProps << std::endl;
138 }
139 else { stream << " Optical properties at " << gMir.photonEnergy.size() << " photon energies" << std::endl; }
140 if (gMir.sigmaAlphaSet) { stream << " Sigma Alpha: " << gMir.sigmaAlpha << std::endl; }
141 stream << " Description: " << gMir.description << std::endl;
142 stream << std::endl;
143
144 return stream;
145}
std::shared_ptr< GLogger > log
void error(int exit_code, Args &&... args) const
Optical boundary (surface) definition belonging to a detector system.
Definition gmirror.h:28
GMirror(const std::string &system, std::vector< std::string > pars, const std::shared_ptr< GLogger > &logger)
Construct a mirror from a serialized parameter list.
Definition gmirror.cc:26
bool isSkinSurface() const
Definition gmirror.cc:98
std::ostream & operator<<(std::ostream &stream, const GMirror &gMir)
Definition gmirror.cc:131
Conventions and shared constants for the detector-system module.
#define GMIRRORSKINSURFACE
Border value marking an optical surface applied to the whole volume skin.
#define ERR_GMIRRORINVALID
#define GMIRRORNUMBEROFPARS
Number of database parameters defining a gmirror entry.
#define ERR_GWRONGNUMBEROFPARS
double getG4Number(const string &v, bool warnIfNotUnit=false)
string removeAllSpacesFromString(const std::string &str)
bool is_unset(std::string_view s)
string removeLeadingAndTrailingSpacesFromString(const std::string &input)