Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/graphics_reps/src/G4AttCheck.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 
 38 G4ThreadLocal G4bool G4AttCheck::fFirst = true;
 39 
 40 G4ThreadLocal std::set<G4String> *G4AttCheck::fUnitCategories = nullptr;
 41 
 42 G4ThreadLocal std::map<G4String,G4String> *G4AttCheck::fStandardUnits = nullptr;
 43 
 44 G4ThreadLocal std::set<G4String> *G4AttCheck::fCategories = nullptr;
 45 
 46 G4ThreadLocal std::set<G4String> *G4AttCheck::fUnits = nullptr;
 47 
 48 G4ThreadLocal std::set<G4String> *G4AttCheck::fValueTypes = nullptr;
 49 
 50 G4AttCheck::G4AttCheck
 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.)...
 86     G4UnitsTable& units = G4UnitDefinition::GetUnitsTable();
 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 
109 void 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 
118 G4bool G4AttCheck::Check(const G4String& leader) const
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 
245 std::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 
328 void 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 
347 G4bool G4AttCheck::Standard
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 =
381                 G4UIcommand::ConvertTo3Vector(value);
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 =
420                   G4UIcommand::ConvertToDimensioned3Vector(valueAndUnit);
421                 AddValuesAndDefs
422                   (standardValues,standardDefinitions,
423                    valueName,valueName+"-X",
424                    G4UIcommand::ConvertToString
425                    (internalValue.x()/valueOfStandardUnit),
426                    standardUnit,
427                    fpDefinitions->find(valueName)->second.GetDesc()+"-X");
428                 AddValuesAndDefs
429                   (standardValues,standardDefinitions,
430                    valueName,valueName+"-Y",
431                    G4UIcommand::ConvertToString
432                    (internalValue.y()/valueOfStandardUnit),
433                    standardUnit,
434                    fpDefinitions->find(valueName)->second.GetDesc()+"-Y");
435                 AddValuesAndDefs
436                   (standardValues,standardDefinitions,
437                    valueName,valueName+"-Z",
438                    G4UIcommand::ConvertToString
439                    (internalValue.z()/valueOfStandardUnit),
440                    standardUnit,
441                    fpDefinitions->find(valueName)->second.GetDesc()+"-Z");
442               } else {
443                 G4double internalValue =
444                   G4UIcommand::ConvertToDimensionedDouble(valueAndUnit);
445                 AddValuesAndDefs
446                   (standardValues,standardDefinitions,
447                    valueName,valueName,
448                    G4UIcommand::ConvertToString
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 }
463