DD4hep  1.28.0
Detector Description Toolkit for High Energy Physics
Handle.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : M.Frank
11 //
12 //==========================================================================
13 
14 #include <DD4hep/detail/Handle.inl>
15 #include <DD4hep/InstanceCount.h>
16 #include <DD4hep/Printout.h>
17 #include <Evaluator/Evaluator.h>
18 
20 #include <iostream>
21 #include <iomanip>
22 #include <climits>
23 #include <cstring>
24 #include <cstdio>
25 
26 #if !defined(WIN32) && !defined(__ICC)
27 #include "cxxabi.h"
28 #endif
29 
30 namespace dd4hep {
31  dd4hep::tools::Evaluator& evaluator();
32 }
33 
34 namespace {
35  const dd4hep::tools::Evaluator& eval(dd4hep::evaluator());
36 }
37 
38 using namespace dd4hep;
39 
40 namespace {
41 
43  static bool s_allow_variable_redefine = true;
44 
46  void check_evaluation(const std::string& value, std::pair<int,double> res, std::stringstream& err) {
47  if ( res.first != tools::Evaluator::OK) {
48  throw std::runtime_error("dd4hep: "+err.str()+" : value="+value+" [Evaluation error]");
49  }
50  }
51 }
52 
53 namespace dd4hep {
54 
56  bool set_allow_variable_redefine(bool value) {
57  bool tmp = s_allow_variable_redefine;
58  s_allow_variable_redefine = value;
59  return tmp;
60  }
61 
62  std::pair<int, double> _toFloatingPoint(const std::string& value) {
63  std::stringstream err;
64  auto result = eval.evaluate(value, err);
65  check_evaluation(value, result, err);
66  return result;
67  }
68 
69  std::pair<int, double> _toInteger(const std::string& value) {
70  std::string s(value);
71  size_t idx = s.find("(int)");
72  if (idx != std::string::npos)
73  s.erase(idx, 5);
74  idx = s.find("(long)");
75  if (idx != std::string::npos)
76  s.erase(idx, 6);
77  while (s[0] == ' ')
78  s.erase(0, 1);
79  return _toFloatingPoint(s);
80  }
81 
82  short _toShort(const std::string& value) {
83  return (short) _toInteger(value).second;
84  }
85 
86  unsigned short _toUShort(const std::string& value) {
87  return (unsigned short) _toInteger(value).second;
88  }
89 
90  int _toInt(const std::string& value) {
91  return (int) _toInteger(value).second;
92  }
93 
94  unsigned int _toUInt(const std::string& value) {
95  return (unsigned int) _toInteger(value).second;
96  }
97 
98  long _toLong(const std::string& value) {
99  return (long) _toInteger(value).second;
100  }
101 
102  unsigned long _toULong(const std::string& value) {
103  return (unsigned long) _toInteger(value).second;
104  }
105 
106  bool _toBool(const std::string& value) {
107  return value == "true" || value == "yes" || value == "True";
108  }
109 
111  float _toFloat(const std::string& value) {
112  return (float) _toFloatingPoint(value).second;
113  }
114 
116  double _toDouble(const std::string& value) {
117  return _toFloatingPoint(value).second;
118  }
119 
121  template <typename T> T _toType(const std::string& value) {
122  notImplemented("Value "+value+" cannot be converted to type "+typeName(typeid(T)));
123  return T();
124  }
125 
127  template <> bool _toType<bool>(const std::string& value) {
128  return _toBool(value);
129  }
130 
132  template <> short _toType<short>(const std::string& value) {
133  return _toShort(value);
134  }
135 
137  template <> unsigned short _toType<unsigned short>(const std::string& value) {
138  return (unsigned short)_toShort(value);
139  }
140 
142  template <> int _toType<int>(const std::string& value) {
143  return _toInt(value);
144  }
145 
147  template <> unsigned int _toType<unsigned int>(const std::string& value) {
148  return (unsigned int)_toInt(value);
149  }
150 
152  template <> long _toType<long>(const std::string& value) {
153  return _toLong(value);
154  }
155 
157  template <> unsigned long _toType<unsigned long>(const std::string& value) {
158  return (unsigned long)_toLong(value);
159  }
160 
162  template <> float _toType<float>(const std::string& value) {
163  return _toFloat(value);
164  }
165 
167  template <> double _toType<double>(const std::string& value) {
168  return _toDouble(value);
169  }
170 
172  template <> std::string _toType<std::string>(const std::string& value) {
173  return value;
174  }
175 
176  template <> char _multiply<char>(const std::string& left, const std::string& right) {
177  double val = _toDouble(left + "*" + right);
178  if ( val >= double(SCHAR_MIN) && val <= double(SCHAR_MAX) )
179  return (char) (int)val;
180  except("_multiply<char>",
181  "Multiplication %e = %s * %s out of bounds for conversion to char.",
182  val, left.c_str(), right.c_str());
183  return 0;
184  }
185 
186  template <> unsigned char _multiply<unsigned char>(const std::string& left, const std::string& right) {
187  double val = _toDouble(left + "*" + right);
188  if ( val >= 0 && val <= double(UCHAR_MAX) )
189  return (unsigned char) (int)val;
190  except("_multiply<unsigned char>",
191  "Multiplication %e = %s * %s out of bounds for conversion to unsigned char.",
192  val, left.c_str(), right.c_str());
193  return 0;
194  }
195 
196  template <> short _multiply<short>(const std::string& left, const std::string& right) {
197  double val = _toDouble(left + "*" + right);
198  if ( val >= double(SHRT_MIN) && val <= double(SHRT_MAX) )
199  return (short) val;
200  except("_multiply<short>",
201  "Multiplication %e = %s * %s out of bounds for conversion to short.",
202  val, left.c_str(), right.c_str());
203  return 0;
204  }
205 
206  template <> unsigned short _multiply<unsigned short>(const std::string& left, const std::string& right) {
207  double val = _toDouble(left + "*" + right);
208  if ( val >= 0 && val <= double(USHRT_MAX) )
209  return (unsigned short)val;
210  except("_multiply<unsigned short>",
211  "Multiplication %e = %s * %s out of bounds for conversion to unsigned short.",
212  val, left.c_str(), right.c_str());
213  return 0;
214  }
215 
216  template <> int _multiply<int>(const std::string& left, const std::string& right) {
217  return (int) _toDouble(left + "*" + right);
218  }
219 
220  template <> unsigned int _multiply<unsigned int>(const std::string& left, const std::string& right) {
221  return (unsigned int) _toDouble(left + "*" + right);
222  }
223 
224  template <> long _multiply<long>(const std::string& left, const std::string& right) {
225  return (long) _toDouble(left + "*" + right);
226  }
227 
228  template <> unsigned long _multiply<unsigned long>(const std::string& left, const std::string& right) {
229  return (unsigned long) _toDouble(left + "*" + right);
230  }
231 
232  template <> float _multiply<float>(const std::string& left, const std::string& right) {
233  return _toFloat(left + "*" + right);
234  }
235 
236  template <> double _multiply<double>(const std::string& left, const std::string& right) {
237  return _toDouble(left + "*" + right);
238  }
239 
240  void _toDictionary(const std::string& name, const std::string& value) {
241  _toDictionary(name, value, "number");
242  }
243 
245  void _toDictionary(const std::string& name, const std::string& value, const std::string& typ) {
246  if ( typ == "string" ) {
247  eval.setEnviron(name.c_str(),value.c_str());
248  return;
249  }
250  else {
251  int status;
252  std::stringstream err;
253  std::string n = name, v = value;
254  size_t idx = v.find("(int)");
255  if (idx != std::string::npos)
256  v.erase(idx, 5);
257  idx = v.find("(float)");
258  if (idx != std::string::npos)
259  v.erase(idx, 7);
260  while (v[0] == ' ')
261  v.erase(0, 1);
262  auto result = eval.evaluate(v, err);
263  check_evaluation(v, result, err);
264  err.str("");
265  status = eval.setVariable(n, result.second, err);
266  if ( status != tools::Evaluator::OK ) {
267  std::stringstream err_msg;
268  err_msg << "name=" << name << " value=" << value
269  << " " << err.str() << " [setVariable error]";
270  if ( status == tools::Evaluator::WARNING_EXISTING_VARIABLE ) {
271  if ( s_allow_variable_redefine )
272  printout(WARNING,"Evaluator","+++ Overwriting variable: "+err_msg.str());
273  else
274  except("Evaluator","+++ Overwriting variable: "+err_msg.str());
275  }
276  }
277  }
278  }
279 
281  std::string _getEnviron(const std::string& env) {
282  // We are trying to deal with the case when several variables are being replaced in the string.
283  size_t current_index = 0;
284  std::stringstream processed_variable;
285  while (true) {
286  // Looking for the start of a variable use, with the syntax
287  // "path1/path2/${VAR1}/path3/${VAR2}"
288  size_t id1 = env.find("${", current_index);
289  // variable start found, do a greedy search for the variable end
290  if (id1 == std::string::npos) {
291  // In this case we did not find the ${ to indicate a start of variable,
292  // we just copy the rest of the variable to the stringstream and exit
293  processed_variable << env.substr(current_index);
294  break;
295  }
296  size_t id2 = env.find("}", id1);
297  if (id2 == std::string::npos) {
298  std::runtime_error("dd4hep: Syntax error, bad variable syntax: " + env);
299  }
300  processed_variable << env.substr(current_index, id1 -current_index );
301  std::string v = env.substr(id1, id2-id1+1);
302  std::stringstream err;
303  auto ret = eval.getEnviron(v, err);
304  // Checking that the variable lookup worked
305  if ( ret.first != tools::Evaluator::OK) {
306  std::cerr << v << ": " << err.str() << std::endl;
307  throw std::runtime_error("dd4hep: Severe error during environment lookup of " + v + " " + err.str());
308  }
309  // Now adding the variable
310  processed_variable << ret.second;
311  current_index = id2 + 1;
312  }
313  return processed_variable.str();
314  }
315 
317  std::string remove_whitespace(const std::string& v) {
318  std::string value;
319  value.reserve(v.length()+1);
320  for(const char* p = v.c_str(); *p; ++p) {
321  if ( !::isspace(*p) ) value += *p;
322  }
323  return value;
324  }
325 
326  template <typename T> static inline std::string __to_string(T value, const char* fmt) {
327  char text[128];
328  ::snprintf(text, sizeof(text), fmt, value);
329  return text;
330  }
331 
332  std::string _toString(bool value) {
333  return value ? "true" : "false";
334  }
335 
336  std::string _toString(short value, const char* fmt) {
337  return __to_string((int)value, fmt);
338  }
339 
340  std::string _toString(int value, const char* fmt) {
341  return __to_string(value, fmt);
342  }
343 
344  std::string _toString(unsigned long value, const char* fmt) {
345  return __to_string(value, fmt);
346  }
347 
348  std::string _toString(float value, const char* fmt) {
349  return __to_string(value, fmt);
350  }
351 
352  std::string _toString(double value, const char* fmt) {
353  return __to_string(value, fmt);
354  }
355 
356  std::string _ptrToString(const void* value, const char* fmt) {
357  return __to_string(value, fmt);
358  }
359 
360  // ==================================================================================
361  static long s_numVerifies = 0;
362 
364  return s_numVerifies;
365  }
367  ++s_numVerifies;
368  }
369  void warning_deprecated_xml_factory(const char* name) {
370  const char* edge = "++++++++++++++++++++++++++++++++++++++++++";
371  size_t len = std::strlen(name);
372  std::cerr << edge << edge << edge << std::endl;
373  std::cerr << "++ The usage of the factory: \"" << name << "\" is DEPRECATED due to naming conventions."
374  << std::setw(53-len) << std::right << "++" << std::endl;
375  std::cerr << "++ Please use \"DD4hep_" << name << "\" instead." << std::setw(93-len) << std::right << "++" << std::endl;
376  std::cerr << edge << edge << edge << std::endl;
377  }
378 }
379 
382 namespace dd4hep {
383  template <> void Handle<_Segmentation>::assign(_Segmentation* s, const std::string& n, const std::string&) {
384  this->m_element = s;
385  s->setName(n);
386  }
387  template <> const char* Handle<_Segmentation>::name() const {
388  return this->m_element ? this->m_element->name().c_str() : "";
389  }
390  template class dd4hep::Handle<_Segmentation>;
391 }
392 
393 #include <DD4hep/Detector.h>
394 #include <TMap.h>
395 #include <TColor.h>
396 
397 template class dd4hep::Handle<NamedObject>;
398 DD4HEP_SAFE_CAST_IMPLEMENTATION(NamedObject,NamedObject)
399 
403 
404 #include <TGeoMedium.h>
405 #include <TGeoMaterial.h>
406 #include <TGeoElement.h>
410 
411 #include <TGeoMatrix.h>
414 DD4HEP_INSTANTIATE_HANDLE(TGeoTranslation);
418 
419 #include <TGeoNode.h>
423 DD4HEP_INSTANTIATE_HANDLE(TGeoNode,TGeoAtt);
426 
427 // Shapes (needed by "Shapes.cpp")
428 #include <TGeoBBox.h>
429 #include <TGeoPcon.h>
430 #include <TGeoPgon.h>
431 #include <TGeoTube.h>
432 #include <TGeoCone.h>
433 #include <TGeoArb8.h>
434 #include <TGeoTrd1.h>
435 #include <TGeoTrd2.h>
436 #include <TGeoParaboloid.h>
437 #include <TGeoSphere.h>
438 #include <TGeoTorus.h>
439 #include <TGeoTessellated.h>
440 #include <TGeoBoolNode.h>
441 #include <TGeoVolume.h>
442 #include <TGeoScaledShape.h>
443 #include <TGeoCompositeShape.h>
444 #include <TGeoShapeAssembly.h>
446 DD4HEP_INSTANTIATE_HANDLE(TGeoVolumeAssembly,TGeoVolume,TGeoAtt);
447 DD4HEP_INSTANTIATE_HANDLE(TGeoVolumeMulti,TGeoVolume,TGeoAtt);
448 DD4HEP_INSTANTIATE_HANDLE(TGeoVolume,TGeoAtt,TAttLine,TAtt3D);
450 DD4HEP_INSTANTIATE_HANDLE(TGeoBBox,TGeoShape);
451 
455 //DD4HEP_INSTANTIATE_SHAPE_HANDLE(MyConeSeg);
461 
465 DD4HEP_INSTANTIATE_SHAPE_HANDLE(TGeoTubeSeg,TGeoTube);
466 DD4HEP_INSTANTIATE_SHAPE_HANDLE(TGeoCtub,TGeoTubeSeg,TGeoTube);
469 
477 
481 
482 // Volume Placements (needed by "Volumes.cpp")
483 #include <TGeoPhysicalNode.h>
484 DD4HEP_INSTANTIATE_HANDLE(TGeoPhysicalNode);
485 
486 #include <TGeoBoolNode.h>
490 
491 // Replicated Volumes (needed by "Volumes.cpp")
492 #include <TGeoPatternFinder.h>
506 DD4HEP_INSTANTIATE_HANDLE_UNNAMED(TGeoPatternHoneycomb);
dd4hep::_toType< bool >
bool _toType< bool >(const std::string &value)
Generic type conversion from string to primitive value.
Definition: Handle.cpp:127
dd4hep::set_allow_variable_redefine
bool set_allow_variable_redefine(bool value)
Steer redefinition of variable re-definition during expression evaluation. returns old value.
Definition: Handle.cpp:56
dd4hep::_toShort
short _toShort(const std::string &value)
String conversions: string to short value.
Definition: Handle.cpp:82
dd4hep::_toBool
bool _toBool(const std::string &value)
String conversions: string to boolean value.
Definition: Handle.cpp:106
dd4hep::_toType< long >
long _toType< long >(const std::string &value)
Generic type conversion from string to primitive value.
Definition: Handle.cpp:152
dd4hep::warning_deprecated_xml_factory
void warning_deprecated_xml_factory(const char *name)
Function tp print warning about deprecated factory usage. Used by Plugin mechanism.
Definition: Handle.cpp:369
dd4hep::increment_object_validations
void increment_object_validations()
Definition: Handle.cpp:366
v
View * v
Definition: MultiView.cpp:28
Detector.h
dd4hep::_toDictionary
void _toDictionary(const std::string &name, const std::string &value)
Enter name value pair to the dictionary. "value" must be a numerical expression, which is evaluated.
Definition: Handle.cpp:240
dd4hep::_multiply< unsigned int >
unsigned int _multiply< unsigned int >(const std::string &left, const std::string &right)
Generic multiplication using the evaluator: result = left * right.
Definition: Handle.cpp:220
_Segmentation
DDSegmentation::Segmentation _Segmentation
Definition: Handle.cpp:381
dd4hep::Handle
Handle: a templated class like a shared pointer, which allows specialized access to tgeometry objects...
Definition: Handle.h:84
dd4hep::_toString
std::string _toString(bool value)
String conversions: boolean value to string.
Definition: Handle.cpp:332
dd4hep::_multiply< short >
short _multiply< short >(const std::string &left, const std::string &right)
Generic multiplication using the evaluator: result = left * right.
Definition: Handle.cpp:196
dd4hep::_toInt
int _toInt(const std::string &value)
String conversions: string to integer value.
Definition: Handle.cpp:90
dd4hep::_multiply< unsigned long >
unsigned long _multiply< unsigned long >(const std::string &left, const std::string &right)
Generic multiplication using the evaluator: result = left * right.
Definition: Handle.cpp:228
dd4hep::Handle::name
const char * name() const
Access the object name (or "" if not supported by the object)
dd4hep::_multiply< int >
int _multiply< int >(const std::string &left, const std::string &right)
Generic multiplication using the evaluator: result = left * right.
Definition: Handle.cpp:216
dd4hep::_toULong
unsigned long _toULong(const std::string &value)
String conversions: string to long integer value.
Definition: Handle.cpp:102
dd4hep::_toLong
long _toLong(const std::string &value)
String conversions: string to long integer value.
Definition: Handle.cpp:98
dd4hep::_toUShort
unsigned short _toUShort(const std::string &value)
String conversions: string to unsigned short value.
Definition: Handle.cpp:86
dd4hep::_toType< unsigned short >
unsigned short _toType< unsigned short >(const std::string &value)
Generic type conversion from string to primitive value.
Definition: Handle.cpp:137
dd4hep::TwistedTubeObject
Concrete object implementation for the Header handle.
Definition: ShapesInterna.h:29
dd4hep::_multiply< float >
float _multiply< float >(const std::string &left, const std::string &right)
Generic multiplication using the evaluator: result = left * right.
Definition: Handle.cpp:232
dd4hep::remove_whitespace
std::string remove_whitespace(const std::string &v)
String manipulations: Remove unconditionally all white spaces.
Definition: Handle.cpp:317
dd4hep::evaluator
const dd4hep::tools::Evaluator & evaluator()
Definition: ExpressionEvaluator.cpp:62
DD4HEP_INSTANTIATE_SHAPE_HANDLE
DD4HEP_INSTANTIATE_SHAPE_HANDLE(TGeoCone)
dd4hep::Handle::assign
void assign(Object *n, const std::string &nam, const std::string &title)
Assign a new named object. Note: object references must be managed by the user.
dd4hep::_toInteger
std::pair< int, double > _toInteger(const std::string &value)
Definition: Handle.cpp:69
ShapesInterna.h
dd4hep::_multiply< unsigned short >
unsigned short _multiply< unsigned short >(const std::string &left, const std::string &right)
Generic multiplication using the evaluator: result = left * right.
Definition: Handle.cpp:206
dd4hep::_multiply< unsigned char >
unsigned char _multiply< unsigned char >(const std::string &left, const std::string &right)
Generic multiplication using the evaluator: result = left * right.
Definition: Handle.cpp:186
dd4hep::_multiply< long >
long _multiply< long >(const std::string &left, const std::string &right)
Generic multiplication using the evaluator: result = left * right.
Definition: Handle.cpp:224
dd4hep::detail::eval
Definition: RootDictionary.h:84
dd4hep::_toType< int >
int _toType< int >(const std::string &value)
Generic type conversion from string to primitive value.
Definition: Handle.cpp:142
TNamed
Class of the ROOT toolkit. See http://root.cern.ch/root/htmldoc/ClassIndex.html.
Definition: ROOTClasses.h:37
dd4hep::_ptrToString
std::string _ptrToString(const void *p, const char *fmt="%p")
Pointer to text conversion.
Definition: Handle.cpp:356
DD4HEP_INSTANTIATE_HANDLE_CODE
DD4HEP_INSTANTIATE_HANDLE_CODE(RAW, TObject, NamedObject)
dd4hep::_toType< short >
short _toType< short >(const std::string &value)
Generic type conversion from string to primitive value.
Definition: Handle.cpp:132
dd4hep::_toFloatingPoint
std::pair< int, double > _toFloatingPoint(const std::string &value)
Definition: Handle.cpp:62
dd4hep::_getEnviron
std::string _getEnviron(const std::string &env)
Evaluate string constant using environment stored in the evaluator.
Definition: Handle.cpp:281
dd4hep::num_object_validations
long num_object_validations()
Definition: Handle.cpp:363
dd4hep::_multiply< char >
char _multiply< char >(const std::string &left, const std::string &right)
Generic multiplication using the evaluator: result = left * right.
Definition: Handle.cpp:176
DD4HEP_INSTANTIATE_HANDLE
DD4HEP_INSTANTIATE_HANDLE(TGeoElement)
dd4hep::_toType< float >
float _toType< float >(const std::string &value)
Generic type conversion from string to primitive value.
Definition: Handle.cpp:162
dd4hep::_toFloat
float _toFloat(const std::string &value)
String conversions: string to float value.
Definition: Handle.cpp:111
dd4hep::_toDouble
double _toDouble(const std::string &value)
String conversions: string to double value.
Definition: Handle.cpp:116
dd4hep::_multiply< double >
double _multiply< double >(const std::string &left, const std::string &right)
Generic multiplication using the evaluator: result = left * right.
Definition: Handle.cpp:236
TObject
Class of the ROOT toolkit. See http://root.cern.ch/root/htmldoc/ClassIndex.html.
Definition: ROOTClasses.h:41
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
dd4hep::NamedObject
Implementation of a named object.
Definition: NamedObject.h:30
dd4hep::_toType
T _toType(const std::string &value)
Generic type conversion from string to primitive value.
Definition: Handle.cpp:121
DD4HEP_INSTANTIATE_HANDLE_UNNAMED
DD4HEP_INSTANTIATE_HANDLE_UNNAMED(Detector)
dd4hep::_toType< unsigned long >
unsigned long _toType< unsigned long >(const std::string &value)
Generic type conversion from string to primitive value.
Definition: Handle.cpp:157
dd4hep::Detector
The main interface to the dd4hep detector description package.
Definition: Detector.h:90
TGeoConeSeg
Class of the ROOT toolkit. See http://root.cern.ch/root/htmldoc/ClassIndex.html.
Definition: ROOTClasses.h:17
dd4hep::DDSegmentation::Segmentation::setName
virtual void setName(const std::string &value)
Set the segmentation name.
Definition: Segmentation.h:100
InstanceCount.h
dd4hep::_toType< unsigned int >
unsigned int _toType< unsigned int >(const std::string &value)
Generic type conversion from string to primitive value.
Definition: Handle.cpp:147
Segmentation.h
dd4hep::DDSegmentation::Segmentation
Base class for all segmentations.
Definition: Segmentation.h:75
Printout.h
dd4hep::_toUInt
unsigned int _toUInt(const std::string &value)
String conversions: string to unsigned integer value.
Definition: Handle.cpp:94
dd4hep::_toType< double >
double _toType< double >(const std::string &value)
Generic type conversion from string to primitive value.
Definition: Handle.cpp:167