gsystem
Loading...
Searching...
No Matches
gmaterial.cc
Go to the documentation of this file.
1
8#include "gutilities.h"
9//using namespace gutilities;
10
11
12// gsystem
13#include "gmaterial.h"
14#include "gsystemConventions.h"
15
16// c++
17#include <iostream>
18#include <sstream>
19
20
21GMaterial::GMaterial(const std::string &s, std::vector<std::string> pars,
22 const std::shared_ptr<GLogger> &logger) : GBase(logger),
23 system(s) {
24 if (pars.size() != GMATERIALNUMBEROFPARS) {
26 "Incorrect number of material parameters for ", pars[0], ". Expected ",
27 GMATERIALNUMBEROFPARS, " but we got ", pars.size());
28 } else {
29 // The parameter vector is a serialized DB/ASCII row. Parsing is positional.
30 size_t i = 0;
31
33 density = stod(gutilities::removeAllSpacesFromString(pars[i++]));
34
35 // The "composition" field is tokenized into (component, amount) pairs.
36 setComponentsFromString(pars[i++]);
37
38 // Human-readable description (kept verbatim).
39 description = pars[i++];
40
41 // Optical properties: each field may be UNINITIALIZEDSTRINGQUANTITY, in which case it is skipped.
42 getMaterialPropertyFromString(pars[i++], "photonEnergy");
43 getMaterialPropertyFromString(pars[i++], "indexOfRefraction");
44 getMaterialPropertyFromString(pars[i++], "absorptionLength");
45 getMaterialPropertyFromString(pars[i++], "reflectivity");
46 getMaterialPropertyFromString(pars[i++], "efficiency");
47
48 // Scintillation properties (spectra first, then scalars).
49 getMaterialPropertyFromString(pars[i++], "fastcomponent");
50 getMaterialPropertyFromString(pars[i++], "slowcomponent");
51
52 // assign_if_set increment index
53 scintillationyieldSet = assign_if_set(pars, i, scintillationyield);
54 resolutionscaleSet = assign_if_set(pars, i, resolutionscale);
55 fasttimeconstantSet = assign_if_set(pars, i, fasttimeconstant);
56 slowtimeconstantSet = assign_if_set(pars, i, slowtimeconstant);
57 yieldratioSet = assign_if_set(pars, i, yieldratio);
58 birksConstantSet = assign_if_set(pars, i, birksConstant);
59
60 // Other optical processes: the final vector load triggers cross-vector size validation.
61 getMaterialPropertyFromString(pars[i++], "rayleigh");
62 }
63}
64
65
66std::ostream &operator<<(std::ostream &stream, const GMaterial &gMat) {
67 stream << std::endl;
68 stream << " - Material: " << gMat.name << " in system " << gMat.system << ": " << std::endl;
69 stream << " Density: " << gMat.density << std::endl;
70 if (!gMat.components.empty()) {
71 stream << " Composition: " << std::endl;
72 for (unsigned m = 0; m < gMat.components.size(); m++) {
73 std::string quantity = gMat.amounts[m] > 1 ? " atoms " : " fractional mass";
74 stream << " ・ " << gMat.components[m] << quantity << " " << gMat.amounts[m] << std::endl;
75 }
76 }
77 stream << " Description: " << gMat.description << std::endl;
78 stream << std::endl;
79
80 return stream;
81}
82
83
84// sets components and amounts
85void GMaterial::setComponentsFromString(const std::string &composition) {
86 std::vector<std::string> allComponents = gutilities::getStringVectorFromString(composition);
87
88 // Interpret alternating tokens as (component, amount) pairs.
89 for (unsigned e = 0; e < allComponents.size() / 2; e++) {
90 components.push_back(allComponents[e * 2]);
91 amounts.push_back(stod(allComponents[e * 2 + 1]));
92 }
93}
94
95
96// load property from DB entry based on its name
97void GMaterial::getMaterialPropertyFromString(const std::string &parameter, const std::string &propertyName) {
98 // Nothing to do if the parameter is not assigned.
99 if (gutilities::removeLeadingAndTrailingSpacesFromString(parameter) == UNINITIALIZEDSTRINGQUANTITY) { return; }
100
101 // Tokenize the string and parse each component to a numeric value with units.
102 std::stringstream parameterComponents(parameter);
103
104 while (!parameterComponents.eof()) {
105 std::string component;
106 parameterComponents >> component;
107
108 // Removing whitespaces.
109 std::string trimmedComponent = gutilities::removeLeadingAndTrailingSpacesFromString(component);
110 // Non set properties
111
112 // Vector-valued properties append one value per token.
113 if (propertyName == "photonEnergy") {
114 photonEnergy.push_back(gutilities::getG4Number(trimmedComponent));
115 } else if (propertyName == "indexOfRefraction") {
116 indexOfRefraction.push_back(gutilities::getG4Number(trimmedComponent));
117 } else if (propertyName == "absorptionLength") {
118 absorptionLength.push_back(gutilities::getG4Number(trimmedComponent));
119 } else if (propertyName == "reflectivity") {
120 reflectivity.push_back(gutilities::getG4Number(trimmedComponent));
121 } else if (propertyName == "efficiency") {
122 efficiency.push_back(gutilities::getG4Number(trimmedComponent));
123 } else if (propertyName == "fastcomponent") {
124 fastcomponent.push_back(gutilities::getG4Number(trimmedComponent));
125 } else if (propertyName == "slowcomponent") {
126 slowcomponent.push_back(gutilities::getG4Number(trimmedComponent));
127 }
128 // Scalar-valued properties overwrite with the last parsed token.
129 else if (propertyName == "scintillationyield") {
130 scintillationyield = gutilities::getG4Number(trimmedComponent);
131 } else if (propertyName == "resolutionscale") {
132 resolutionscale = gutilities::getG4Number(trimmedComponent);
133 } else if (propertyName == "fasttimeconstant") {
134 fasttimeconstant = gutilities::getG4Number(trimmedComponent);
135 } else if (propertyName == "slowtimeconstant") {
136 slowtimeconstant = gutilities::getG4Number(trimmedComponent);
137 } else if (propertyName == "yieldratio") {
138 yieldratio = gutilities::getG4Number(trimmedComponent);
139 } else if (propertyName == "birkConstant") {
140 birksConstant = gutilities::getG4Number(trimmedComponent);
141 } else if (propertyName == "rayleigh") {
142 rayleigh.push_back(gutilities::getG4Number(trimmedComponent));
143 }
144
145 // validation triggered by rayleigh
146 if (propertyName == "rayleigh") {
147 // Rayleigh is loaded last: at this point we can validate that all other optical vectors
148 // either are empty (not specified) or match the photonEnergy vector length.
149 //
150 // If they do not match, behavior is undefined because properties would be evaluated
151 // at inconsistent energy grids.
152 unsigned long photonEnergyVectorSize = photonEnergy.size();
153
154 if (!indexOfRefraction.empty() && indexOfRefraction.size() != photonEnergyVectorSize) {
156 "indexOfRefraction size ", indexOfRefraction.size(), " mismatch: photonEnergy has size ",
157 photonEnergyVectorSize);
158 }
159 if (!absorptionLength.empty() && absorptionLength.size() != photonEnergyVectorSize) {
161 "absorptionLength size ", absorptionLength.size(), " mismatch: photonEnergy has size ",
162 photonEnergyVectorSize);
163 }
164 if (!reflectivity.empty() && reflectivity.size() != photonEnergyVectorSize) {
166 "reflectivity size ", reflectivity.size(), " mismatch: photonEnergy has size ",
167 photonEnergyVectorSize);
168 }
169 if (!efficiency.empty() && efficiency.size() != photonEnergyVectorSize) {
171 "efficiency size ", efficiency.size(), " mismatch: photonEnergy has size ",
172 photonEnergyVectorSize);
173 }
174 if (!fastcomponent.empty() && fastcomponent.size() != photonEnergyVectorSize) {
176 "fastcomponent size ", fastcomponent.size(), " mismatch: photonEnergy has size ",
177 photonEnergyVectorSize);
178 }
179 if (!slowcomponent.empty() && slowcomponent.size() != photonEnergyVectorSize) {
181 "slowcomponent size ", slowcomponent.size(), " mismatch: photonEnergy has size ",
182 photonEnergyVectorSize);
183 }
184 if (!rayleigh.empty() && rayleigh.size() != photonEnergyVectorSize) {
186 "rayleigh size ", rayleigh.size(), " mismatch: photonEnergy has size ",
187 photonEnergyVectorSize);
188 }
189 }
190 }
191}
192
193
194bool GMaterial::assign_if_set(const std::vector<std::string> &pars, size_t &i, double &out) {
195 if (i >= pars.size()) return false;
196
197 const std::string trimmed =
199
200 std::string_view sv(trimmed);
201 if (gutilities::is_unset(sv)) return false;
202
203 try {
204 out = std::stod(trimmed);
205 return true;
206 } catch (const std::exception &) {
207 // Do not error here: malformed optional scalars are treated as "not set".
208 return false;
209 }
210}
std::shared_ptr< GLogger > log
void error(int exit_code, Args &&... args) const
Material definition belonging to a detector system.
Definition gmaterial.h:28
GMaterial(const std::string &system, std::vector< std::string > pars, const std::shared_ptr< GLogger > &logger)
Construct a material from a serialized parameter list.
Definition gmaterial.cc:21
std::ostream & operator<<(std::ostream &stream, const GMaterial &gMat)
Definition gmaterial.cc:66
Conventions and shared constants for the detector-system module.
#define GMATERIALNUMBEROFPARS
Number of database parameters defining a gmaterial entry.
#define ERR_GMATERIALOPTICALPROPERTYMISMATCH
#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)
vector< std::string > getStringVectorFromString(const std::string &input)