gsystem
Loading...
Searching...
No Matches
gmirror.cc
Go to the documentation of this file.
1
7
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() != gsystem::GMIRRORNUMBEROFPARS) {
30 log->error(gsystem::ERR_GWRONGNUMBEROFPARS,
31 "Incorrect number of mirror parameters for ", pars[0], ". Expected ",
32 gsystem::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(gsystem::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(gsystem::ERR_GMIRRORINVALID, "mirror <", name, ">: could not parse sigmaAlpha <",
76 sigmaAlphaPar, ">");
77 }
78 }
79
80 // The boundary needs optical properties from one of the two sources.
81 if (matOptProps.empty() && photonEnergy.empty()) {
82 log->error(gsystem::ERR_GMIRRORINVALID, "mirror <", name,
83 ">: no optical properties. Set matOptProps or photonEnergy with the properties tables");
84 }
85
86 // Every provided property vector must be evaluated on the photonEnergy grid.
87 for (const auto& [property, values] : std::initializer_list<std::pair<const char*, const std::vector<double>&>>{
88 {"indexOfRefraction", indexOfRefraction}, {"reflectivity", reflectivity},
89 {"efficiency", efficiency}, {"specularlobe", specularlobe},
90 {"specularspike", specularspike}, {"backscatter", backscatter},
91 {"transmittance", transmittance}}) {
92 if (!values.empty() && values.size() != photonEnergy.size()) {
93 log->error(gsystem::ERR_GMIRRORINVALID, "mirror <", name, ">: property <", property, "> has ",
94 values.size(), " entries but photonEnergy has ", photonEnergy.size());
95 }
96 }
97}
98
99bool GMirror::isSkinSurface() const { return border == gsystem::GMIRRORSKINSURFACE; }
100
101void GMirror::getMirrorPropertyFromString(const std::string& parameter, const std::string& propertyName) {
102 // Nothing to do if the parameter is not assigned.
103 if (mirror_field_is_unset(parameter)) { return; }
104
105 // Tokenize the string and parse each component to a numeric value with units.
106 std::stringstream parameterComponents(parameter);
107
108 while (!parameterComponents.eof()) {
109 std::string component;
110 parameterComponents >> component;
111
112 std::string trimmedComponent = gutilities::removeLeadingAndTrailingSpacesFromString(component);
113 if (trimmedComponent.empty()) { continue; }
114
115 if (propertyName == "photonEnergy") { photonEnergy.push_back(gutilities::getG4Number(trimmedComponent)); }
116 else if (propertyName == "indexOfRefraction") {
117 indexOfRefraction.push_back(gutilities::getG4Number(trimmedComponent));
118 }
119 else if (propertyName == "reflectivity") { reflectivity.push_back(gutilities::getG4Number(trimmedComponent)); }
120 else if (propertyName == "efficiency") { efficiency.push_back(gutilities::getG4Number(trimmedComponent)); }
121 else if (propertyName == "specularlobe") { specularlobe.push_back(gutilities::getG4Number(trimmedComponent)); }
122 else if (propertyName == "specularspike") {
123 specularspike.push_back(gutilities::getG4Number(trimmedComponent));
124 }
125 else if (propertyName == "backscatter") { backscatter.push_back(gutilities::getG4Number(trimmedComponent)); }
126 else if (propertyName == "transmittance") {
127 transmittance.push_back(gutilities::getG4Number(trimmedComponent));
128 }
129 }
130}
131
132std::ostream& operator<<(std::ostream& stream, const GMirror& gMir) {
133 stream << std::endl;
134 stream << " - Mirror: " << gMir.name << " in system " << gMir.system << ": " << std::endl;
135 stream << " Type / Finish / Model: " << gMir.type << " / " << gMir.finish << " / " << gMir.model << std::endl;
136 stream << " Border: " << gMir.border << std::endl;
137 if (!gMir.matOptProps.empty()) {
138 stream << " Optical properties from material: " << gMir.matOptProps << std::endl;
139 }
140 else { stream << " Optical properties at " << gMir.photonEnergy.size() << " photon energies" << std::endl; }
141 if (gMir.sigmaAlphaSet) { stream << " Sigma Alpha: " << gMir.sigmaAlpha << std::endl; }
142 stream << " Description: " << gMir.description << std::endl;
143 stream << std::endl;
144
145 return stream;
146}
GBase(const std::shared_ptr< GOptions > &gopt, std::string logger_name="")
std::shared_ptr< GLogger > log
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:99
std::ostream & operator<<(std::ostream &stream, const GMirror &gMir)
Definition gmirror.cc:132
Conventions and shared constants for the detector-system module.
constexpr char GMIRRORSKINSURFACE[]
Border value marking an optical surface applied to the whole volume skin.
constexpr int GMIRRORNUMBEROFPARS
Number of database parameters defining a gmirror entry.
constexpr int ERR_GMIRRORINVALID
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)