Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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)
Definition: G4AttCheck.cc:245
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
Definition: G4UnitsTable.hh:68
void print(G4double elem)
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition: G4ios.hh:57
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
Definition: G4AttCheck.cc:118
G4bool Standard(std::vector< G4AttValue > *standardValues, std::map< G4String, G4AttDef > *standardDefinitions) const
Definition: G4AttCheck.cc:348
static G4ThreeVector ConvertTo3Vector(const char *st)
Definition: G4UIcommand.cc:601
static G4String ConvertToString(G4bool boolVal)
Definition: G4UIcommand.cc:446
static G4double ConvertToDimensionedDouble(const char *st)
Definition: G4UIcommand.cc:588
static G4ThreeVector ConvertToDimensioned3Vector(const char *st)
Definition: G4UIcommand.cc:612
static G4double GetValueOf(const G4String &)
static G4String GetCategory(const G4String &)
static G4UnitsTable & GetUnitsTable()
G4bool GetStoreKey(const std::map< G4String, G4AttDef > *definitions, G4String &key)
G4String strip_copy(G4String str, char ch=' ')
Return copy of string with leading and trailing characters removed.
#define G4ThreadLocal
Definition: tls.hh:77