CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
DDAlgoArguments.cc
Go to the documentation of this file.
2 #include <DD4hep/Path.h>
3 #include <DD4hep/Printout.h>
4 #include <DD4hep/Detector.h>
5 #include <DD4hep/Filter.h>
6 #include <DD4hep/Grammar.h>
7 
8 #include <TClass.h>
9 
10 #include <algorithm>
11 #include <stdexcept>
12 
13 using namespace std;
14 using namespace cms;
15 using namespace dd4hep;
16 
17 //
18 // Helpers to create 3D rotation matrix from angles
19 //
20 dd4hep::Rotation3D cms::makeRotation3D(
21  double thetaX, double phiX, double thetaY, double phiY, double thetaZ, double phiZ) {
22  dd4hep::Position posX(sin(thetaX) * cos(phiX), sin(thetaX) * sin(phiX), cos(thetaX));
23  dd4hep::Position posY(sin(thetaY) * cos(phiY), sin(thetaY) * sin(phiY), cos(thetaY));
24  dd4hep::Position posZ(sin(thetaZ) * cos(phiZ), sin(thetaZ) * sin(phiZ), cos(thetaZ));
25  dd4hep::Rotation3D rotation(posX, posY, posZ);
26 
27  return rotation;
28 }
29 
30 // makes sure that the RotationMatrix built is
31 // LEFT-handed coordinate system (i.e. reflected)
32 dd4hep::Rotation3D cms::makeRotReflect(
33  double thetaX, double phiX, double thetaY, double phiY, double thetaZ, double phiZ) {
34  // define 3 unit std::vectors forming the new left-handed axes
35  DD3Vector x(cos(phiX) * sin(thetaX), sin(phiX) * sin(thetaX), cos(thetaX));
36  DD3Vector y(cos(phiY) * sin(thetaY), sin(phiY) * sin(thetaY), cos(thetaY));
37  DD3Vector z(cos(phiZ) * sin(thetaZ), sin(phiZ) * sin(thetaZ), cos(thetaZ));
38 
39  constexpr double tol = 1.0e-3; // Geant4 compatible
40  double check = (x.Cross(y)).Dot(z); // in case of a LEFT-handed orthogonal system this must be -1
41  if (abs(1. + check) > tol) {
42  except("DD4CMS", "+++ FAILED to construct Rotation is not LEFT-handed!");
43  }
44 
45  dd4hep::Rotation3D rotation(x.x(), y.x(), z.x(), x.y(), y.y(), z.y(), x.z(), y.z(), z.z());
46 
47  return rotation;
48 }
49 
50 dd4hep::Rotation3D cms::makeRotation3D(dd4hep::Rotation3D rotation, const std::string& axis, double angle) {
51  switch (hash(axis)) {
52  case hash("x"):
53  rotation = dd4hep::RotationX(angle);
54  break;
55  case hash("y"):
56  rotation = dd4hep::RotationY(angle);
57  break;
58  case hash("z"):
59  rotation = dd4hep::RotationZ(angle);
60  break;
61  default:
62  throw std::runtime_error("Axis is not valid.");
63  }
64  return rotation;
65 }
66 
67 namespace {
68 
69  std::string& ltrim(std::string& str, const std::string& chars = "\t\n\v\f\r ") {
70  str.erase(0, str.find_first_not_of(chars));
71  return str;
72  }
73 
74  std::string& rtrim(std::string& str, const std::string& chars = "\t\n\v\f\r ") {
75  str.erase(str.find_last_not_of(chars) + 1);
76  return str;
77  }
78 
79  std::string& trimWhitespace(std::string& str, const std::string& chars = "\t\n\v\f\r ") {
80  return ltrim(rtrim(str, chars), chars);
81  }
82 
83  std::string trimSVecWhitespace(std::string& str) {
84  std::string res;
85 
86  vector<string_view> v = dd::split(str, ",");
87  for (auto& n : v) {
88  std::string ts{n.data(), n.size()};
89  trimWhitespace(ts);
90  res.append(ts).append(",");
91  };
92 
93  res.erase(res.find_last_of(','));
94 
95  return res;
96  }
97 } // namespace
98 
99 DDAlgoArguments::DDAlgoArguments(cms::DDParsingContext& ctxt, xml_h elt) : context(ctxt), element(elt) {
100  name = xml_dim_t(element).nameStr();
101 }
102 
106  xml_dim_t e(element);
107  string val = n.realName(xml_dim_t(e.child(DD_CMU(rParent))).nameStr());
108  return val;
109 }
110 
114  return n.realName(value<string>("ChildName"));
115 }
116 
118 bool DDAlgoArguments::find(const string& nam) const {
119  for (xml_coll_t p(element, _U(star)); p; ++p) {
120  string n = p.attr<string>(_U(name));
121  if (n == nam) {
122  return true;
123  }
124  }
125  return false;
126 }
127 
129 xml_h DDAlgoArguments::rawArgument(const string& nam) const {
130  for (xml_coll_t p(element, _U(star)); p; ++p) {
131  string n = p.attr<string>(_U(name));
132  if (n == nam) {
133  return std::move(p);
134  }
135  }
136  except("DD4CMS", "+++ Attempt to access non-existing algorithm option %s[%s]", name.c_str(), nam.c_str());
137  throw runtime_error("DDCMS: Attempt to access non-existing algorithm option.");
138 }
139 
141 string DDAlgoArguments::resolved_scalar_arg(const string& nam) const {
143  xml_h arg = rawArgument(nam);
144  string val = arg.attr<string>(_U(value));
145  return ns.realName(val);
146 }
147 
148 string DDAlgoArguments::resolveValue(const std::string& aValue) const {
150  string value(aValue);
151  size_t idx = value.find('[');
152  if (idx == string::npos) {
153  return value;
154  }
155 
156  while (idx != string::npos) {
157  ++idx;
158  size_t idp = value.find(':', idx);
159  size_t idq = value.find(']', idx);
160  if (idp == string::npos || idp > idq)
161  value.insert(idx, ns.name());
162  else if (idp != string::npos && idp < idq)
163  value[idp] = NAMESPACE_SEP;
164  idx = value.find('[', idx);
165  }
166 
167  string rep;
168  string& v = value;
169  size_t idq;
170  for (idx = v.find('[', 0); idx != string::npos; idx = v.find('[', idx + 1)) {
171  idq = v.find(']', idx + 1);
172  rep = v.substr(idx + 1, idq - idx - 1);
173  auto r = ns.context()->description.constants().find(rep);
174  if (r != ns.context()->description.constants().end()) {
175  rep = "(" + r->second->type + ")";
176  v.replace(idx, idq - idx + 1, rep);
177  }
178  }
179  return value;
180 }
181 
182 namespace {
183 
185  vector<string> raw_vector(const DDAlgoArguments* a, xml_h arg) {
186  xml_dim_t xp(arg);
187  vector<string> data;
188  cms::DDNamespace ns(a->context);
189  string val = xp.text();
190  string nam = xp.nameStr();
191  string typ = xp.typeStr();
192  string numValue = xp.attr<string>(DD_CMU(nEntries));
193  int num = _toDouble(numValue);
194  const BasicGrammar& gr = BasicGrammar::instance<vector<string> >();
195 
196  val = trimSVecWhitespace(val);
197  val = '[' + ns.realName(val) + ']';
198  int res = gr.fromString(&data, val);
199  if (!res) {
200  except(
201  "DD4CMS", "+++ VectorParam<%s>: %s -> %s [Invalid conversion:%d]", typ.c_str(), nam.c_str(), val.c_str(), res);
202  } else if (num != (int)data.size()) {
203  except("DD4CMS",
204  "+++ VectorParam<%s>: %s -> %s [Invalid entry count: %d <> %ld]",
205  typ.c_str(),
206  nam.c_str(),
207  val.c_str(),
208  num,
209  data.size());
210  }
211  printout(a->context.debug_algorithms ? ALWAYS : DEBUG,
212  "DD4CMS",
213  "+++ VectorParam<%s>: ret=%d %s -> %s",
214  typ.c_str(),
215  res,
216  nam.c_str(),
217  gr.str(&data).c_str());
218  return data;
219  }
220 
221  template <typename T>
222  T __cnv(const string&) {
223  return 0;
224  }
225  template <>
226  double __cnv<double>(const string& arg) {
227  return _toDouble(arg);
228  }
229  template <>
230  float __cnv<float>(const string& arg) {
231  return _toFloat(arg);
232  }
233  template <>
234  long __cnv<long>(const string& arg) {
235  return _toLong(arg);
236  }
237  template <>
238  int __cnv<int>(const string& arg) {
239  return _toInt(arg);
240  }
241  template <>
242  string __cnv<string>(const string& arg) {
243  return arg;
244  }
245 
246  template <typename T>
247  vector<T> __cnvVect(const DDAlgoArguments* a, const char* req_typ, xml_h xp) {
248  cms::DDNamespace ns(a->context);
249  string piece;
250  string nam = xp.attr<string>(_U(name));
251  string typ = xp.hasAttr(_U(type)) ? xp.attr<string>(_U(type)) : "numeric";
252  string val = xp.text();
253  string nValues = a->resolveValue(xp.attr<string>(DD_CMU(nEntries)));
254  int num = _toInt(nValues);
255  if (typ != req_typ) {
256  except("DD4CMS",
257  "+++ VectorParam<%s | %s>: %s -> <%s> %s [Incompatible vector-type]",
258  req_typ,
259  typ.c_str(),
260  nam.c_str(),
261  typeName(typeid(T)).c_str(),
262  val.c_str());
263  }
264  vector<T> data;
265  val = remove_whitespace(val);
266 
267  if (!val.empty())
268  val += ',';
269  for (size_t idx = 0, idq = val.find(',', idx); idx != string::npos && idq != string::npos;
270  idx = ++idq, idq = val.find(',', idx)) {
271  piece = ns.realName(val.substr(idx, idq - idx));
272  T d = __cnv<T>(piece);
273  data.push_back(d);
274  }
275  printout(a->context.debug_algorithms ? ALWAYS : DEBUG,
276  "DD4CMS",
277  "+++ VectorParam<%s>: %s[%d] -> %s",
278  typ.c_str(),
279  nam.c_str(),
280  num,
281  val.c_str());
282  return data;
283  }
284 } // namespace
285 
287 namespace cms {
288 
290  template <typename T>
291  T DDAlgoArguments::value(const string& nam) const {
292  return __cnv<T>(resolved_scalar_arg(nam));
293  }
294 
295  template double DDAlgoArguments::value<double>(const string& nam) const;
296  template float DDAlgoArguments::value<float>(const string& nam) const;
297  template long DDAlgoArguments::value<long>(const string& nam) const;
298  template int DDAlgoArguments::value<int>(const string& nam) const;
299  template string DDAlgoArguments::value<string>(const string& nam) const;
300 
302  template <>
303  vector<string> DDAlgoArguments::value<vector<string> >(const string& nam) const {
304  return raw_vector(this, rawArgument(nam));
305  }
306 
308  template <>
309  vector<double> DDAlgoArguments::value<vector<double> >(const string& nam) const {
310  return __cnvVect<double>(this, "numeric", rawArgument(nam));
311  }
312 
314  template <>
315  vector<float> DDAlgoArguments::value<vector<float> >(const string& nam) const {
316  return __cnvVect<float>(this, "numeric", rawArgument(nam));
317  }
318 
320  template <>
321  vector<long> DDAlgoArguments::value<vector<long> >(const string& nam) const {
322  return __cnvVect<long>(this, "numeric", rawArgument(nam));
323  }
324 
326  template <>
327  vector<int> DDAlgoArguments::value<vector<int> >(const string& nam) const {
328  return __cnvVect<int>(this, "numeric", rawArgument(nam));
329  }
330 } // namespace cms
331 
333 string DDAlgoArguments::str(const string& nam) const { return this->value<string>(nam); }
334 
336 double DDAlgoArguments::dble(const string& nam) const { return this->value<double>(resolveValue(nam)); }
337 
339 int DDAlgoArguments::integer(const string& nam) const { return this->value<int>(nam); }
340 
342 vector<double> DDAlgoArguments::vecDble(const string& nam) const { return this->value<vector<double> >(nam); }
343 
345 vector<float> DDAlgoArguments::vecFloat(const string& nam) const { return this->value<vector<float> >(nam); }
346 
348 vector<int> DDAlgoArguments::vecInt(const string& nam) const { return this->value<vector<int> >(nam); }
349 
351 vector<string> DDAlgoArguments::vecStr(const string& nam) const { return this->value<vector<string> >(nam); }
std::string childName() const
Access value of child&#39;name from the xml element.
string rep
Definition: cuy.py:1189
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >> DD3Vector
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
T value(const std::string &name) const
A arg
Definition: Factorize.h:31
int integer(const std::string &nam) const
Shortcut to access integer arguments.
DDRotationMatrix makeRotation3D(double thetaX, double phiX, double thetaY, double phiY, double thetaZ, double phiZ)
static void ltrim(std::string &s)
DDParsingContext *const context() const
Definition: DDNamespace.h:76
std::string_view name() const
Definition: DDNamespace.h:79
tuple d
Definition: ztail.py:151
tuple dd4hep
Definition: dd4hep_cff.py:3
xml_h rawArgument(const std::string &name) const
Access raw argument as a string by name.
std::string realName(const std::string &) const
Definition: DDNamespace.cc:106
DDRotationMatrix makeRotReflect(double thetaX, double phiX, double thetaY, double phiY, double thetaZ, double phiZ)
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
def move
Definition: eostools.py:511
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define DD_CMU(a)
Definition: DDXMLTags.h:183
std::string resolveValue(const std::string &value) const
static void rtrim(std::string &s)
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:79
double a
Definition: hdecay.h:119
#define DEBUG
Definition: DMRChecker.cc:120
std::vector< double > vecDble(const std::string &nam) const
Shortcut to access vector&lt;double&gt; arguments.
double dble(const std::string &nam) const
Shortcut to access double arguments.
dd4hep::Detector & description
cms::DDParsingContext & context
std::vector< std::string > vecStr(const std::string &nam) const
Shortcut to access vector&lt;string&gt; arguments.
#define str(s)
bool find(const std::string &name) const
Check the existence of an argument by name.
long double T
std::vector< int > vecInt(const std::string &nam) const
Shortcut to access vector&lt;int&gt; arguments.
std::vector< float > vecFloat(const std::string &nam) const
Shortcut to access vector&lt;float&gt; arguments.
std::string resolved_scalar_arg(const std::string &name) const
Access namespace resolved argument as a string by name.
std::string parentName() const
Access value of rParent child node.
std::string str(const std::string &nam) const
Shortcut to access string arguments.
#define NAMESPACE_SEP
Definition: DDNamespace.h:92
T angle(T x1, T y1, T z1, T x2, T y2, T z2)
Definition: angle.h:11