Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4AttCheck.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27
28#include "G4AttCheck.hh"
29
30#include "globals.hh"
31
32#include "G4AttDef.hh"
33#include "G4AttDefStore.hh"
34#include "G4AttValue.hh"
35#include "G4UnitsTable.hh"
36#include "G4UIcommand.hh"
37
38G4ThreadLocal G4bool G4AttCheck::fFirst = true;
39
40G4ThreadLocal std::set<G4String> *G4AttCheck::fUnitCategories = nullptr;
41
42G4ThreadLocal std::map<G4String,G4String> *G4AttCheck::fStandardUnits = nullptr;
43
44G4ThreadLocal std::set<G4String> *G4AttCheck::fCategories = nullptr;
45
46G4ThreadLocal std::set<G4String> *G4AttCheck::fUnits = nullptr;
47
48G4ThreadLocal std::set<G4String> *G4AttCheck::fValueTypes = nullptr;
49
51(const std::vector<G4AttValue>* values,
52 const std::map<G4String,G4AttDef>* definitions):
53 fpValues(values),
54 fpDefinitions(definitions)
55{
56 Init();
57
58 if (fFirst) { // Initialise static containers.
59 fFirst = false;
60
61 // Legal Unit Category Types...
62 fUnitCategories->insert("Length");
63 fUnitCategories->insert("Energy");
64 fUnitCategories->insert("Time");
65 fUnitCategories->insert("Electric charge");
66 fUnitCategories->insert("Volumic Mass"); // (Density)
67
68 // Corresponding Standard Units...
69 (*fStandardUnits)["Length"] = "m";
70 (*fStandardUnits)["Energy"] = "MeV";
71 (*fStandardUnits)["Time"] = "ns";
72 (*fStandardUnits)["Electric charge"] = "e+";
73 (*fStandardUnits)["Volumic Mass"] = "kg/m3";
74
75 // Legal Categories...
76 fCategories->insert("Bookkeeping");
77 fCategories->insert("Draw");
78 fCategories->insert("Physics");
79 fCategories->insert("PickAction");
80 fCategories->insert("Association");
81
82 // Legal units...
83 fUnits->insert("");
84 fUnits->insert("G4BestUnit");
85 // ...plus any legal unit symbol ("MeV", "km", etc.)...
87 for (size_t i = 0; i < units.size(); ++i) {
88 if (fUnitCategories->find(units[i]->GetName()) !=
89 fUnitCategories->end()) {
90 //G4cout << units[i]->GetName() << G4endl;
91 G4UnitsContainer& container = units[i]->GetUnitsList();
92 for (auto & j : container) {
93 //G4cout << container[j]->GetName() << ' '
94 // << container[j]->GetSymbol() << G4endl;
95 fUnits->insert(j->GetSymbol());
96 }
97 }
98 }
99
100 // Legal Value Types...
101 fValueTypes->insert("G4String");
102 fValueTypes->insert("G4int");
103 fValueTypes->insert("G4double");
104 fValueTypes->insert("G4ThreeVector");
105 fValueTypes->insert("G4bool");
106 }
107}
108
109void G4AttCheck::Init()
110{
111 if (fValueTypes == nullptr) fValueTypes = new std::set<G4String>;
112 if (fUnits == nullptr) fUnits = new std::set<G4String>;
113 if (fCategories == nullptr) fCategories = new std::set<G4String>;
114 if (fStandardUnits == nullptr) fStandardUnits = new std::map<G4String,G4String>;
115 if (fUnitCategories == nullptr) fUnitCategories = new std::set<G4String>;
116}
117
119{
120 // Check only. Silent unless error - then G4cerr. Returns error.
121 G4bool error = false;
122 static G4ThreadLocal G4int iError = 0;
123 G4bool print = false;
124 if (iError < 10 || iError%100 == 0) {
125 print = true;
126 }
127 using namespace std;
128 if (fpValues == nullptr) return error; // A null values vector is a valid situation.
129 if (fpDefinitions == nullptr) {
130 ++iError;
131 error = true;
132 if (print) {
133 G4cerr <<
134 "\n*******************************************************";
135 if (!leader.empty()) {
136 G4cerr << '\n' << leader;
137 }
138 G4cerr <<
139 "\nG4AttCheck: ERROR " << iError << ": Null definitions pointer"
140 "\n*******************************************************"
141 << G4endl;
142 }
143 return error;
144 }
145 vector<G4AttValue>::const_iterator iValue;
146 for (iValue = fpValues->begin(); iValue != fpValues->end(); ++iValue) {
147 const G4String& valueName = iValue->GetName();
148 const G4String& value = iValue->GetValue();
149 // NOLINTNEXTLINE(modernize-use-auto): Explicitly want a const_iterator
150 map<G4String,G4AttDef>::const_iterator iDef =
151 fpDefinitions->find(valueName);
152 if (iDef == fpDefinitions->end()) {
153 ++iError;
154 error = true;
155 if (print) {
156 G4cerr <<
157 "\n*******************************************************";
158 if (!leader.empty()) {
159 G4cerr << '\n' << leader;
160 }
161 G4cerr <<
162 "\nG4AttCheck: ERROR " << iError << ": No G4AttDef for G4AttValue \""
163 << valueName << "\": " << value <<
164 "\n*******************************************************"
165 << G4endl;
166 }
167 } else {
168 const G4String& category = iDef->second.GetCategory();
169 const G4String& extra = iDef->second.GetExtra();
170 const G4String& valueType = iDef->second.GetValueType();
171 if (fCategories->find(category) == fCategories->end()) {
172 ++iError;
173 error = true;
174 if (print) {
175 G4cerr <<
176 "\n*******************************************************";
177 if (!leader.empty()) {
178 G4cerr << '\n' << leader;
179 }
180 G4cerr <<
181 "\nG4AttCheck: ERROR " << iError << ": Illegal Category Field \""
182 << category << "\" for G4AttValue \""
183 << valueName << "\": " << value <<
184 "\n Possible Categories:";
185 set<G4String>::iterator i;
186 for (i = fCategories->begin(); i != fCategories->end(); ++i) {
187 G4cerr << ' ' << *i;
188 }
189 G4cerr <<
190 "\n*******************************************************"
191 << G4endl;
192 }
193 }
194 if(category == "Physics" && fUnits->find(extra) == fUnits->end()) {
195 ++iError;
196 error = true;
197 if (print) {
198 G4cerr <<
199 "\n*******************************************************";
200 if (!leader.empty()) {
201 G4cerr << '\n' << leader;
202 }
203 G4cerr <<
204 "\nG4AttCheck: ERROR " << iError << ": Illegal Extra field \""
205 << extra << "\" for G4AttValue \""
206 << valueName << "\": " << value <<
207 "\n Possible Extra fields if Category==\"Physics\":\n ";
208 set<G4String>::iterator i;
209 for (i = fUnits->begin(); i != fUnits->end(); ++i) {
210 G4cerr << ' ' << *i;
211 }
212 G4cerr <<
213 "\n*******************************************************"
214 << G4endl;
215 }
216 }
217 if (fValueTypes->find(valueType) == fValueTypes->end()) {
218 ++iError;
219 error = true;
220 if (print) {
221 G4cerr <<
222 "\n*******************************************************";
223 if (!leader.empty()) {
224 G4cerr << '\n' << leader;
225 }
226 G4cerr <<
227 "\nG4AttCheck: ERROR " << iError << ": Illegal Value Type field \""
228 << valueType << "\" for G4AttValue \""
229 << valueName << "\": " << value <<
230 "\n Possible Value Types:";
231 set<G4String>::iterator i;
232 for (i = fValueTypes->begin(); i != fValueTypes->end(); ++i) {
233 G4cerr << ' ' << *i;
234 }
235 G4cerr <<
236 "\n*******************************************************"
237 << G4endl;
238 }
239 }
240 }
241 }
242 return error;
243}
244
245std::ostream& operator<< (std::ostream& os, const G4AttCheck& ac)
246{
247 using namespace std;
248 if (ac.fpDefinitions == nullptr) {
249 os << "G4AttCheck: ERROR: zero definitions pointer." << endl;
250 return os;
251 }
252 G4String storeKey;
253 if (G4AttDefStore::GetStoreKey(ac.fpDefinitions, storeKey)) {
254 os << storeKey << ':' << endl;
255 }
256 if (ac.fpValues == nullptr) {
257 // A null values vector is a valid situation.
258 os << "G4AttCheck: zero values pointer." << endl;
259 return os;
260 }
261 vector<G4AttValue>::const_iterator iValue;
262 for (iValue = ac.fpValues->begin(); iValue != ac.fpValues->end(); ++iValue) {
263 const G4String& valueName = iValue->GetName();
264 const G4String& value = iValue->GetValue();
265 // NOLINTNEXTLINE(modernize-use-auto): Explicitly want a const_iterator
266 map<G4String,G4AttDef>::const_iterator iDef =
267 ac.fpDefinitions->find(valueName);
268 G4bool error = false;
269 if (iDef == ac.fpDefinitions->end()) {
270 error = true;
271 os << "G4AttCheck: ERROR: No G4AttDef for G4AttValue \""
272 << valueName << "\": " << value << endl;
273 } else {
274 const G4String& category = iDef->second.GetCategory();
275 const G4String& extra = iDef->second.GetExtra();
276 const G4String& valueType = iDef->second.GetValueType();
277 if (ac.fCategories->find(category) == ac.fCategories->end()) {
278 error = true;
279 os <<
280 "G4AttCheck: ERROR: Illegal Category Field \"" << category
281 << "\" for G4AttValue \"" << valueName << "\": " << value <<
282 "\n Possible Categories:";
283 set<G4String>::iterator i;
284 for (i = ac.fCategories->begin(); i != ac.fCategories->end(); ++i) {
285 os << ' ' << *i;
286 }
287 os << endl;
288 }
289 if(category == "Physics" && ac.fUnits->find(extra) == ac.fUnits->end()) {
290 error = true;
291 os <<
292 "G4AttCheck: ERROR: Illegal Extra field \""<< extra
293 << "\" for G4AttValue \"" << valueName << "\": " << value <<
294 "\n Possible Extra fields if Category==\"Physics\":\n ";
295 set<G4String>::iterator i;
296 for (i = ac.fUnits->begin(); i != ac.fUnits->end(); ++i) {
297 os << ' ' << *i;
298 }
299 os << endl;
300 }
301 if (ac.fValueTypes->find(valueType) == ac.fValueTypes->end()) {
302 error = true;
303 os <<
304 "G4AttCheck: ERROR: Illegal Value Type field \"" << valueType
305 << "\" for G4AttValue \"" << valueName << "\": " << value <<
306 "\n Possible Value Types:";
307 set<G4String>::iterator i;
308 for (i = ac.fValueTypes->begin(); i != ac.fValueTypes->end(); ++i) {
309 os << ' ' << *i;
310 }
311 os << endl;
312 }
313 }
314 if (!error) {
315 os << iDef->second.GetDesc()
316 << " (" << valueName
317 << "): " << value;
318 if (iDef->second.GetCategory() == "Physics" &&
319 !iDef->second.GetExtra().empty()) {
320 os << " (" << iDef->second.GetExtra() << ")";
321 }
322 os << endl;
323 }
324 }
325 return os;
326}
327
328void G4AttCheck::AddValuesAndDefs
329(std::vector<G4AttValue>* standardValues,
330 std::map<G4String,G4AttDef>* standardDefinitions,
331 const G4String& oldName,
332 const G4String& name,
333 const G4String& value,
334 const G4String& extra,
335 const G4String& description) const
336{
337 // Add new G4AttDeff...
338 standardValues->push_back(G4AttValue(name,value,""));
339 // Copy original G4AttDef...
340 (*standardDefinitions)[name] = fpDefinitions->find(oldName)->second;
341 // ...and make appropriate changes...
342 (*standardDefinitions)[name].SetName(name);
343 (*standardDefinitions)[name].SetExtra(extra);
344 if (!description.empty()) (*standardDefinitions)[name].SetDesc(description);
345}
346
348(std::vector<G4AttValue>* standardValues,
349 std::map<G4String,G4AttDef>* standardDefinitions) const
350{
351 // Places standard versions in provided vector and map and returns error.
352 // Assumes valid input. Use Check to check.
353 using namespace std;
354 G4bool error = false;
355 vector<G4AttValue>::const_iterator iValue;
356 for (iValue = fpValues->begin(); iValue != fpValues->end(); ++iValue) {
357 const G4String& valueName = iValue->GetName();
358 const G4String& value = iValue->GetValue();
359 // NOLINTNEXTLINE(modernize-use-auto): Explicitly want a const_iterator
360 map<G4String,G4AttDef>::const_iterator iDef =
361 fpDefinitions->find(valueName);
362 if (iDef == fpDefinitions->end()) {
363 error = true;
364 } else {
365 const G4String& category = iDef->second.GetCategory();
366 const G4String& extra = iDef->second.GetExtra();
367 const G4String& valueType = iDef->second.GetValueType();
368 if (fCategories->find(category) == fCategories->end() ||
369 (category == "Physics" && fUnits->find(extra) == fUnits->end()) ||
370 fValueTypes->find(valueType) == fValueTypes->end()) {
371 error = true;
372 } else {
373 if (category != "Physics") { // Simply copy...
374 standardValues->push_back(*iValue);
375 (*standardDefinitions)[valueName] =
376 fpDefinitions->find(valueName)->second;
377 } else { // "Physics"...
378 if (extra.empty()) { // Dimensionless...
379 if (valueType == "G4ThreeVector") { // Split vector into 3...
380 G4ThreeVector internalValue =
382 AddValuesAndDefs
383 (standardValues,standardDefinitions,
384 valueName,valueName+"-X",
385 G4UIcommand::ConvertToString(internalValue.x()),"",
386 fpDefinitions->find(valueName)->second.GetDesc()+"-X");
387 AddValuesAndDefs
388 (standardValues,standardDefinitions,
389 valueName,valueName+"-Y",
390 G4UIcommand::ConvertToString(internalValue.y()),"",
391 fpDefinitions->find(valueName)->second.GetDesc()+"-Y");
392 AddValuesAndDefs
393 (standardValues,standardDefinitions,
394 valueName,valueName+"-Z",
395 G4UIcommand::ConvertToString(internalValue.z()),"",
396 fpDefinitions->find(valueName)->second.GetDesc()+"-Z");
397 } else { // Simply copy...
398 standardValues->push_back(*iValue);
399 (*standardDefinitions)[valueName] =
400 fpDefinitions->find(valueName)->second;
401 }
402 } else { // Dimensioned...
403 G4String valueAndUnit;
404 G4String unit;
405 if (extra == "G4BestUnit") {
406 valueAndUnit = G4StrUtil::strip_copy(value);
407 unit = valueAndUnit.substr(valueAndUnit.rfind(' ')+1);
408 } else {
409 valueAndUnit = G4StrUtil::strip_copy(value + ' ' + extra);
410 unit = extra;
411 }
412 G4String unitCategory = G4UnitDefinition::GetCategory(unit);
413 if (fUnitCategories->find(unitCategory) != fUnitCategories->end()) {
414 G4String standardUnit = (*fStandardUnits)[unitCategory];
415 G4double valueOfStandardUnit =
416 G4UnitDefinition::GetValueOf(standardUnit);
417// G4String exstr = iDef->second.GetExtra();
418 if (valueType == "G4ThreeVector") { // Split vector into 3...
419 G4ThreeVector internalValue =
421 AddValuesAndDefs
422 (standardValues,standardDefinitions,
423 valueName,valueName+"-X",
425 (internalValue.x()/valueOfStandardUnit),
426 standardUnit,
427 fpDefinitions->find(valueName)->second.GetDesc()+"-X");
428 AddValuesAndDefs
429 (standardValues,standardDefinitions,
430 valueName,valueName+"-Y",
432 (internalValue.y()/valueOfStandardUnit),
433 standardUnit,
434 fpDefinitions->find(valueName)->second.GetDesc()+"-Y");
435 AddValuesAndDefs
436 (standardValues,standardDefinitions,
437 valueName,valueName+"-Z",
439 (internalValue.z()/valueOfStandardUnit),
440 standardUnit,
441 fpDefinitions->find(valueName)->second.GetDesc()+"-Z");
442 } else {
443 G4double internalValue =
445 AddValuesAndDefs
446 (standardValues,standardDefinitions,
447 valueName,valueName,
449 (internalValue/valueOfStandardUnit),
450 standardUnit);
451 }
452 }
453 }
454 }
455 }
456 }
457 }
458 if (error) {
459 G4cerr << "G4AttCheck::Standard: Conversion error." << G4endl;
460 }
461 return error;
462}
std::ostream & operator<<(std::ostream &os, const G4AttCheck &ac)
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
std::vector< G4UnitDefinition * > G4UnitsContainer
std::vector< G4UnitsCategory * > G4UnitsTable
void print(G4double elem)
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition G4ios.hh:67
double z() const
double x() const
double y() const
G4AttCheck(const std::vector< G4AttValue > *values, const std::map< G4String, G4AttDef > *definitions)
Definition G4AttCheck.cc:51
G4bool Check(const G4String &leader="") const
G4bool Standard(std::vector< G4AttValue > *standardValues, std::map< G4String, G4AttDef > *standardDefinitions) const
static G4ThreeVector ConvertTo3Vector(const char *st)
static G4String ConvertToString(G4bool boolVal)
static G4double ConvertToDimensionedDouble(const char *st)
static G4ThreeVector ConvertToDimensioned3Vector(const char *st)
static G4double GetValueOf(const G4String &)
static G4String GetCategory(const G4String &)
static G4UnitsTable & GetUnitsTable()
G4bool GetStoreKey(const std::map< G4String, G4AttDef > *definitions, G4String &key)
#define G4ThreadLocal
Definition tls.hh:77