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(
31 gsystem::ERR_GWRONGNUMBEROFPARS,
32 "Incorrect number of mirror parameters for %1. Expected %2 but we got %3", pars[0],
33 gsystem::GMIRRORNUMBEROFPARS, pars.size());
34 }
35
36 // The parameter vector is a serialized DB/ASCII row. Parsing is positional.
37 size_t i = 0;
38
41
42 // Geant4 surface configuration: all mandatory.
44 finish = gutilities::removeAllSpacesFromString(pars[i++]);
46 border = gutilities::removeAllSpacesFromString(pars[i++]);
47
48 for (const auto& [field, value] : std::initializer_list<std::pair<const char*, const std::string&>>{
49 {"type", type}, {"finish", finish}, {"model", model}, {"border", border}}) {
50 if (mirror_field_is_unset(value)) {
51 log->error(
52 gsystem::ERR_GMIRRORINVALID, "mirror <%1>: mandatory field <%2> is not set", name, field);
53 }
54 }
55
56 // Boundary optical properties: a material name or the explicit tables below.
57 matOptProps = gutilities::removeAllSpacesFromString(pars[i++]);
58 if (mirror_field_is_unset(matOptProps)) { matOptProps.clear(); }
59
60 getMirrorPropertyFromString(pars[i++], "photonEnergy");
61 getMirrorPropertyFromString(pars[i++], "indexOfRefraction");
62 getMirrorPropertyFromString(pars[i++], "reflectivity");
63 getMirrorPropertyFromString(pars[i++], "efficiency");
64 getMirrorPropertyFromString(pars[i++], "specularlobe");
65 getMirrorPropertyFromString(pars[i++], "specularspike");
66 getMirrorPropertyFromString(pars[i++], "backscatter");
67 getMirrorPropertyFromString(pars[i++], "transmittance");
68
69 std::string sigmaAlphaPar = gutilities::removeLeadingAndTrailingSpacesFromString(pars[i++]);
70 // GEMC2 used -1 to mark an unset sigmaAlpha; treat it as unset for compatibility.
71 if (!mirror_field_is_unset(sigmaAlphaPar) && sigmaAlphaPar != "-1") {
72 try {
73 sigmaAlpha = std::stod(sigmaAlphaPar);
74 sigmaAlphaSet = true;
75 }
76 catch (const std::exception&) {
77 log->error(
78 gsystem::ERR_GMIRRORINVALID, "mirror <%1>: could not parse sigmaAlpha <%2>", name,
79 sigmaAlphaPar);
80 }
81 }
82
83 // The boundary needs optical properties from one of the two sources.
84 if (matOptProps.empty() && photonEnergy.empty()) {
85 log->error(
87 "mirror <%1>: no optical properties. Set matOptProps or photonEnergy with the properties tables",
88 name);
89 }
90
91 // Every provided property vector must be evaluated on the photonEnergy grid.
92 for (const auto& [property, values] : std::initializer_list<std::pair<const char*, const std::vector<double>&>>{
93 {"indexOfRefraction", indexOfRefraction}, {"reflectivity", reflectivity},
94 {"efficiency", efficiency}, {"specularlobe", specularlobe},
95 {"specularspike", specularspike}, {"backscatter", backscatter},
96 {"transmittance", transmittance}}) {
97 if (!values.empty() && values.size() != photonEnergy.size()) {
98 log->error(
100 "mirror <%1>: property <%2> has %3 entries but photonEnergy has %4", name, property,
101 values.size(), photonEnergy.size());
102 }
103 }
104}
105
106bool GMirror::isSkinSurface() const { return border == gsystem::GMIRRORSKINSURFACE; }
107
108void GMirror::getMirrorPropertyFromString(const std::string& parameter, const std::string& propertyName) {
109 // Nothing to do if the parameter is not assigned.
110 if (mirror_field_is_unset(parameter)) { return; }
111
112 // Tokenize the string and parse each component to a numeric value with units.
113 std::stringstream parameterComponents(parameter);
114
115 while (!parameterComponents.eof()) {
116 std::string component;
117 parameterComponents >> component;
118
119 std::string trimmedComponent = gutilities::removeLeadingAndTrailingSpacesFromString(component);
120 if (trimmedComponent.empty()) { continue; }
121
122 if (propertyName == "photonEnergy") { photonEnergy.push_back(gutilities::getG4Number(trimmedComponent)); }
123 else if (propertyName == "indexOfRefraction") {
124 indexOfRefraction.push_back(gutilities::getG4Number(trimmedComponent));
125 }
126 else if (propertyName == "reflectivity") { reflectivity.push_back(gutilities::getG4Number(trimmedComponent)); }
127 else if (propertyName == "efficiency") { efficiency.push_back(gutilities::getG4Number(trimmedComponent)); }
128 else if (propertyName == "specularlobe") { specularlobe.push_back(gutilities::getG4Number(trimmedComponent)); }
129 else if (propertyName == "specularspike") {
130 specularspike.push_back(gutilities::getG4Number(trimmedComponent));
131 }
132 else if (propertyName == "backscatter") { backscatter.push_back(gutilities::getG4Number(trimmedComponent)); }
133 else if (propertyName == "transmittance") {
134 transmittance.push_back(gutilities::getG4Number(trimmedComponent));
135 }
136 }
137}
138
139std::ostream& operator<<(std::ostream& stream, const GMirror& gMir) {
140 stream << std::endl;
141 stream << " - Mirror: " << gMir.name << " in system " << gMir.system << ": " << std::endl;
142 stream << " Type / Finish / Model: " << gMir.type << " / " << gMir.finish << " / " << gMir.model << std::endl;
143 stream << " Border: " << gMir.border << std::endl;
144 if (!gMir.matOptProps.empty()) {
145 stream << " Optical properties from material: " << gMir.matOptProps << std::endl;
146 }
147 else { stream << " Optical properties at " << gMir.photonEnergy.size() << " photon energies" << std::endl; }
148 if (gMir.sigmaAlphaSet) { stream << " Sigma Alpha: " << gMir.sigmaAlpha << std::endl; }
149 stream << " Description: " << gMir.description << std::endl;
150 stream << std::endl;
151
152 return stream;
153}
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:106
std::ostream & operator<<(std::ostream &stream, const GMirror &gMir)
Definition gmirror.cc:139
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)