CMS 3D CMS Logo

DDDefinitions2Objects.cc
Go to the documentation of this file.
1 #include "DD4hep/DetFactoryHelper.h"
2 #include "DD4hep/DetectorHelper.h"
3 #include "DD4hep/DD4hepUnits.h"
4 #include "DD4hep/GeoHandler.h"
5 #include "DD4hep/Printout.h"
6 #include "DD4hep/Plugins.h"
7 #include "DD4hep/detail/SegmentationsInterna.h"
8 #include "DD4hep/detail/DetectorInterna.h"
9 #include "DD4hep/detail/ObjectsInterna.h"
10 #include "DD4hep/MatrixHelpers.h"
11 
12 #include "XML/Utilities.h"
20 
21 #include "TGeoManager.h"
22 #include "TGeoMaterial.h"
23 
24 #include <climits>
25 #include <iostream>
26 #include <iomanip>
27 #include <map>
28 #include <vector>
29 #include <unordered_map>
30 #include <utility>
31 
32 #define EDM_ML_DEBUG
33 
34 using namespace std;
35 using namespace dd4hep;
36 using namespace cms;
37 using namespace cms_units::operators;
38 
39 namespace dd4hep {
40 
41  namespace {
42 
43  atomic<UInt_t> unique_mat_id = 0xAFFEFEED;
44 
45  class include_constants;
46  class include_load;
47  class include_unload;
48  class print_xml_doc;
49 
50  class ConstantsSection;
51  class DDLConstant;
52 
53  struct DDRegistry {
54  std::vector<xml::Document> includes;
55  std::unordered_map<std::string, std::string> unresolvedConst;
56  std::unordered_map<std::string, std::string> originalConst;
57  };
58 
59  class MaterialSection;
62 
63  class RotationSection;
64  class DDLRotation;
65  class DDLReflectionRotation;
66  class DDLRotationSequence;
67  class DDLRotationByAxis;
68  class DDLTransform3D;
69 
70  class PosPartSection;
71  class DDLPosPart;
72  class DDLDivision;
73 
74  class LogicalPartSection;
75  class DDLLogicalPart;
76 
77  class SolidSection;
78  class DDLExtrudedPolygon;
79  class DDLShapeless;
80  class DDLTrapezoid;
81  class DDLEllipticalTube;
82  class DDLPseudoTrap;
83  class DDLPolyhedra;
84  class DDLPolycone;
85  class DDLTorus;
86  class DDLTrd1;
87  class DDLTrd2;
88  class DDLTruncTubs;
89  class DDLCutTubs;
90  class DDLTubs;
91  class DDLBox;
92  class DDLCone;
93  class DDLSphere;
94  class DDLUnionSolid;
95  class DDLIntersectionSolid;
96  class DDLSubtractionSolid;
97 
98  class DDLAlgorithm;
99  class DDLVector;
100 
101  class SpecParSection;
102  class DDLSpecPar;
103  class PartSelector;
104  class Parameter;
105 
106  class debug;
107  } // namespace
108 
109  TGeoCombiTrans* createPlacement(const Rotation3D& iRot, const Position& iTrans) {
110  double elements[9];
111  iRot.GetComponents(elements);
112  TGeoRotation r;
113  r.SetMatrix(elements);
114 
115  TGeoTranslation t(iTrans.x(), iTrans.y(), iTrans.z());
116 
117  return new TGeoCombiTrans(t, r);
118  }
119 
121  template <>
122  void Converter<debug>::operator()(xml_h element) const;
123  template <>
124  void Converter<print_xml_doc>::operator()(xml_h element) const;
125 
127  template <>
128  void Converter<ConstantsSection>::operator()(xml_h element) const;
129  template <>
130  void Converter<DDLConstant>::operator()(xml_h element) const;
131  template <>
132  void Converter<DDRegistry>::operator()(xml_h element) const;
133 
135  template <>
136  void Converter<MaterialSection>::operator()(xml_h element) const;
137  template <>
138  void Converter<DDLElementaryMaterial>::operator()(xml_h element) const;
139  template <>
140  void Converter<DDLCompositeMaterial>::operator()(xml_h element) const;
141 
143  template <>
144  void Converter<RotationSection>::operator()(xml_h element) const;
146  template <>
147  void Converter<DDLRotation>::operator()(xml_h element) const;
149  template <>
150  void Converter<DDLReflectionRotation>::operator()(xml_h element) const;
152  template <>
153  void Converter<DDLRotationSequence>::operator()(xml_h element) const;
155  template <>
156  void Converter<DDLRotationByAxis>::operator()(xml_h element) const;
157  template <>
158  void Converter<DDLTransform3D>::operator()(xml_h element) const;
159 
161  template <>
162  void Converter<LogicalPartSection>::operator()(xml_h element) const;
163  template <>
164  void Converter<DDLLogicalPart>::operator()(xml_h element) const;
165 
167  template <>
168  void Converter<PosPartSection>::operator()(xml_h element) const;
170  template <>
171  void Converter<DDLPosPart>::operator()(xml_h element) const;
173  template <>
174  void Converter<DDLDivision>::operator()(xml_h element) const;
175 
177  template <>
178  void Converter<SpecParSection>::operator()(xml_h element) const;
179  template <>
180  void Converter<DDLSpecPar>::operator()(xml_h element) const;
181  template <>
182  void Converter<PartSelector>::operator()(xml_h element) const;
183  template <>
184  void Converter<Parameter>::operator()(xml_h element) const;
185 
187  template <>
188  void Converter<SolidSection>::operator()(xml_h element) const;
190  template <>
191  void Converter<DDLUnionSolid>::operator()(xml_h element) const;
193  template <>
194  void Converter<DDLSubtractionSolid>::operator()(xml_h element) const;
196  template <>
197  void Converter<DDLIntersectionSolid>::operator()(xml_h element) const;
199  template <>
200  void Converter<DDLPseudoTrap>::operator()(xml_h element) const;
202  template <>
203  void Converter<DDLExtrudedPolygon>::operator()(xml_h element) const;
205  template <>
206  void Converter<DDLShapeless>::operator()(xml_h element) const;
208  template <>
209  void Converter<DDLTrapezoid>::operator()(xml_h element) const;
211  template <>
212  void Converter<DDLPolycone>::operator()(xml_h element) const;
214  template <>
215  void Converter<DDLPolyhedra>::operator()(xml_h element) const;
217  template <>
218  void Converter<DDLEllipticalTube>::operator()(xml_h element) const;
220  template <>
221  void Converter<DDLTorus>::operator()(xml_h element) const;
223  template <>
224  void Converter<DDLTubs>::operator()(xml_h element) const;
226  template <>
227  void Converter<DDLCutTubs>::operator()(xml_h element) const;
229  template <>
230  void Converter<DDLTruncTubs>::operator()(xml_h element) const;
232  template <>
233  void Converter<DDLSphere>::operator()(xml_h element) const;
235  template <>
236  void Converter<DDLTrd1>::operator()(xml_h element) const;
238  template <>
239  void Converter<DDLTrd2>::operator()(xml_h element) const;
241  template <>
242  void Converter<DDLCone>::operator()(xml_h element) const;
244  template <>
245  void Converter<DDLBox>::operator()(xml_h element) const;
247  template <>
248  void Converter<DDLAlgorithm>::operator()(xml_h element) const;
250  template <>
251  void Converter<DDLVector>::operator()(xml_h element) const;
252 
254  template <>
255  void Converter<include_load>::operator()(xml_h element) const;
257  template <>
258  void Converter<include_unload>::operator()(xml_h element) const;
260  template <>
261  void Converter<include_constants>::operator()(xml_h element) const;
262 } // namespace dd4hep
263 
265 template <>
266 void Converter<ConstantsSection>::operator()(xml_h element) const {
267  cms::DDNamespace ns(_param<cms::DDParsingContext>(), element);
268  cms::DDParsingContext* const context = ns.context();
269  xml_coll_t(element, DD_CMU(Constant)).for_each(Converter<DDLConstant>(description, context, optional));
270  xml_coll_t(element, DD_CMU(Vector)).for_each(Converter<DDLVector>(description, context, optional));
271 }
272 
274 template <>
275 void Converter<MaterialSection>::operator()(xml_h element) const {
276  cms::DDNamespace ns(_param<cms::DDParsingContext>(), element);
277  xml_coll_t(element, DD_CMU(ElementaryMaterial))
278  .for_each(Converter<DDLElementaryMaterial>(description, ns.context(), optional));
279  xml_coll_t(element, DD_CMU(CompositeMaterial))
280  .for_each(Converter<DDLCompositeMaterial>(description, ns.context(), optional));
281 }
282 
283 template <>
284 void Converter<RotationSection>::operator()(xml_h element) const {
285  cms::DDNamespace ns(_param<cms::DDParsingContext>(), element);
286  xml_coll_t(element, DD_CMU(Rotation)).for_each(Converter<DDLRotation>(description, ns.context(), optional));
287  xml_coll_t(element, DD_CMU(ReflectionRotation))
288  .for_each(Converter<DDLReflectionRotation>(description, ns.context(), optional));
289  xml_coll_t(element, DD_CMU(RotationSequence))
290  .for_each(Converter<DDLRotationSequence>(description, ns.context(), optional));
291  xml_coll_t(element, DD_CMU(RotationByAxis))
292  .for_each(Converter<DDLRotationByAxis>(description, ns.context(), optional));
293 }
294 
295 template <>
296 void Converter<PosPartSection>::operator()(xml_h element) const {
297  cms::DDNamespace ns(_param<cms::DDParsingContext>(), element);
298  xml_coll_t(element, DD_CMU(Division)).for_each(Converter<DDLDivision>(description, ns.context(), optional));
299  xml_coll_t(element, DD_CMU(PosPart)).for_each(Converter<DDLPosPart>(description, ns.context(), optional));
300  xml_coll_t(element, DD_CMU(Algorithm)).for_each(Converter<DDLAlgorithm>(description, ns.context(), optional));
301 }
302 
303 template <>
304 void Converter<SpecParSection>::operator()(xml_h element) const {
305  cms::DDNamespace ns(_param<cms::DDParsingContext>(), element);
306  xml_coll_t(element, DD_CMU(SpecPar)).for_each(Converter<DDLSpecPar>(description, ns.context(), optional));
307 }
308 
309 template <>
310 void Converter<DDLSpecPar>::operator()(xml_h element) const {
311  cms::DDNamespace ns(_param<cms::DDParsingContext>(), element);
312  xml_coll_t(element, DD_CMU(PartSelector)).for_each(Converter<PartSelector>(description, ns.context(), optional));
313  xml_coll_t(element, DD_CMU(Parameter)).for_each(Converter<Parameter>(description, ns.context(), optional));
314 }
315 
317 template <>
318 void Converter<LogicalPartSection>::operator()(xml_h element) const {
319  cms::DDNamespace ns(_param<cms::DDParsingContext>(), element);
320  xml_coll_t(element, DD_CMU(LogicalPart)).for_each(Converter<DDLLogicalPart>(description, ns.context(), optional));
321 }
322 
324 template <>
325 void Converter<SolidSection>::operator()(xml_h element) const {
326  cms::DDNamespace ns(_param<cms::DDParsingContext>(), element);
327  for (xml_coll_t solid(element, _U(star)); solid; ++solid) {
328  using cms::hash;
329  switch (hash(solid.tag())) {
330  case hash("Box"):
331  Converter<DDLBox>(description, ns.context(), optional)(solid);
332  break;
333  case hash("Polycone"):
334  Converter<DDLPolycone>(description, ns.context(), optional)(solid);
335  break;
336  case hash("Polyhedra"):
337  Converter<DDLPolyhedra>(description, ns.context(), optional)(solid);
338  break;
339  case hash("Tubs"):
340  Converter<DDLTubs>(description, ns.context(), optional)(solid);
341  break;
342  case hash("CutTubs"):
343  Converter<DDLCutTubs>(description, ns.context(), optional)(solid);
344  break;
345  case hash("TruncTubs"):
346  Converter<DDLTruncTubs>(description, ns.context(), optional)(solid);
347  break;
348  case hash("Tube"):
349  Converter<DDLTubs>(description, ns.context(), optional)(solid);
350  break;
351  case hash("Trd1"):
352  Converter<DDLTrd1>(description, ns.context(), optional)(solid);
353  break;
354  case hash("Trd2"):
355  Converter<DDLTrd2>(description, ns.context(), optional)(solid);
356  break;
357  case hash("Cone"):
358  Converter<DDLCone>(description, ns.context(), optional)(solid);
359  break;
360  case hash("Sphere"):
361  Converter<DDLSphere>(description, ns.context(), optional)(solid);
362  break;
363  case hash("EllipticalTube"):
364  Converter<DDLEllipticalTube>(description, ns.context(), optional)(solid);
365  break;
366  case hash("Torus"):
367  Converter<DDLTorus>(description, ns.context(), optional)(solid);
368  break;
369  case hash("PseudoTrap"):
370  Converter<DDLPseudoTrap>(description, ns.context(), optional)(solid);
371  break;
372  case hash("ExtrudedPolygon"):
373  Converter<DDLExtrudedPolygon>(description, ns.context(), optional)(solid);
374  break;
375  case hash("Trapezoid"):
376  Converter<DDLTrapezoid>(description, ns.context(), optional)(solid);
377  break;
378  case hash("UnionSolid"):
379  Converter<DDLUnionSolid>(description, ns.context(), optional)(solid);
380  break;
381  case hash("SubtractionSolid"):
382  Converter<DDLSubtractionSolid>(description, ns.context(), optional)(solid);
383  break;
384  case hash("IntersectionSolid"):
385  Converter<DDLIntersectionSolid>(description, ns.context(), optional)(solid);
386  break;
387  case hash("ShapelessSolid"):
388  Converter<DDLShapeless>(description, ns.context(), optional)(solid);
389  break;
390  default:
391  throw std::runtime_error("Request to process unknown shape '" + xml_dim_t(solid).nameStr() + "' [" +
392  solid.tag() + "]");
393  break;
394  }
395  }
396 }
397 
399 template <>
400 void Converter<DDLConstant>::operator()(xml_h element) const {
401  cms::DDNamespace ns(_param<cms::DDParsingContext>());
402  DDRegistry* res = _option<DDRegistry>();
403  xml_dim_t constant = element;
404  xml_dim_t par = constant.parent();
405  bool eval = par.hasAttr(_U(eval)) ? par.attr<bool>(_U(eval)) : true;
406  string val = constant.valueStr();
407  string nam = constant.nameStr();
408  string real = ns.prepend(nam);
409  string typ = eval ? "number" : "string";
410  size_t idx = val.find('[');
411 
412  if (constant.hasAttr(_U(type)))
413  typ = constant.typeStr();
414 
415  if (idx == string::npos || typ == "string") {
416  try {
417  ns.addConstant(nam, val, typ);
418  res->originalConst[real] = val;
419  } catch (const exception& e) {
420 #ifdef EDM_ML_DEBUG
421 
422  printout(INFO,
423  "DD4CMS",
424  "++ Unresolved constant: %s = %s [%s]. Try to resolve later. [%s]",
425  real.c_str(),
426  val.c_str(),
427  typ.c_str(),
428  e.what());
429 #endif
430  }
431  return;
432  }
433  // Setup the resolution mechanism in Converter<resolve>
434  while (idx != string::npos) {
435  ++idx;
436  size_t idp = val.find(':', idx);
437  size_t idq = val.find(']', idx);
438  if (idp == string::npos || idp > idq)
439  val.insert(idx, ns.name());
440  else if (idp != string::npos && idp < idq)
441  val[idp] = NAMESPACE_SEP;
442  idx = val.find('[', idx);
443  }
444 
445 #ifdef EDM_ML_DEBUG
446 
447  printout(
448  ns.context()->debug_constants ? ALWAYS : DEBUG, "Constant", "Unresolved: %s -> %s", real.c_str(), val.c_str());
449 
450 #endif
451 
452  res->originalConst[real] = val;
453  res->unresolvedConst[real] = val;
454 }
455 
457 template <>
458 void Converter<DDLElementaryMaterial>::operator()(xml_h element) const {
459  cms::DDNamespace ns(_param<cms::DDParsingContext>());
460  xml_dim_t xmat(element);
461  string nam = ns.prepend(xmat.nameStr());
462  TGeoManager& mgr = description.manager();
463  TGeoMaterial* mat = mgr.GetMaterial(nam.c_str());
464  if (nullptr == mat) {
465  const char* matname = nam.c_str();
466  double density = xmat.attr<double>(DD_CMU(density)) / (dd4hep::g / dd4hep::cm3);
467  int atomicNumber = xmat.attr<int>(DD_CMU(atomicNumber));
468  double atomicWeight = xmat.attr<double>(DD_CMU(atomicWeight)) / (dd4hep::g / dd4hep::mole);
469  TGeoElementTable* tab = mgr.GetElementTable();
470  int nElem = tab->GetNelements();
471 
472 #ifdef EDM_ML_DEBUG
473 
474  printout(ns.context()->debug_materials ? ALWAYS : DEBUG, "DD4CMS", "+++ Element table size = %d", nElem);
475 
476 #endif
477 
478  if (nElem <= 1) { // Restore the element table DD4hep destroyed.
479  tab->TGeoElementTable::~TGeoElementTable();
480  new (tab) TGeoElementTable();
481  tab->BuildDefaultElements();
482  }
483  TGeoMixture* mix = new TGeoMixture(nam.c_str(), 1, density);
484  TGeoElement* elt = tab->FindElement(xmat.nameStr().c_str());
485 
486 #ifdef EDM_ML_DEBUG
487 
488  printout(ns.context()->debug_materials ? ALWAYS : DEBUG,
489  "DD4CMS",
490  "+++ Searching for material %-48s elt_ptr = %ld",
491  xmat.nameStr().c_str(),
492  elt);
493 
494  printout(ns.context()->debug_materials ? ALWAYS : DEBUG,
495  "DD4CMS",
496  "+++ Converting material %-48s Atomic weight %8.3f [g/mol], Atomic number %u, Density: %8.3f [g/cm3] "
497  "ROOT: %8.3f [g/cm3]",
498  ('"' + nam + '"').c_str(),
499  atomicWeight,
500  atomicNumber,
501  density,
502  mix->GetDensity());
503 
504 #endif
505 
506  bool newMatDef = false;
507 
508  if (elt) {
509  // A is Mass of a mole in Geant4 units for atoms with atomic shell
510 
511 #ifdef EDM_ML_DEBUG
512 
513  printout(ns.context()->debug_materials ? ALWAYS : DEBUG,
514  "DD4CMS",
515  " ROOT definition of %-50s Atomic weight %g, Atomic number %u, Number of nucleons %u",
516  elt->GetName(),
517  elt->A(),
518  elt->Z(),
519  elt->N());
520  printout(ns.context()->debug_materials ? ALWAYS : DEBUG,
521  "DD4CMS",
522  "+++ Compared to XML values: Atomic weight %g, Atomic number %u",
523  atomicWeight,
524  atomicNumber);
525 #endif
526 
527  static constexpr double const weightTolerance = 1.0e-6;
528  if (atomicNumber != elt->Z() ||
529  (std::abs(atomicWeight - elt->A()) > (weightTolerance * (atomicWeight + elt->A()))))
530  newMatDef = true;
531  }
532 
533  if (!elt || newMatDef) {
534  if (newMatDef) {
535 #ifdef EDM_ML_DEBUG
536 
537  printout(ns.context()->debug_materials ? ALWAYS : DEBUG,
538  "DD4CMS Warning",
539  "+++ Converter<ElementaryMaterial> Different definition of a default element with name:%s [CREATE NEW "
540  "MATERIAL]",
541  matname);
542 
543 #endif
544 
545  } else {
546 #ifdef EDM_ML_DEBUG
547 
548  printout(ns.context()->debug_materials ? ALWAYS : DEBUG,
549  "DD4CMS Warning",
550  "+++ Converter<ElementaryMaterial> No default element present with name:%s [CREATE NEW MATERIAL]",
551  matname);
552 
553 #endif
554  }
555  elt = new TGeoElement(xmat.nameStr().c_str(), "CMS element", atomicNumber, atomicWeight);
556  }
557 
558  mix->AddElement(elt, 1.0);
559  mix->SetTemperature(ns.context()->description.stdConditions().temperature);
560  mix->SetPressure(ns.context()->description.stdConditions().pressure);
561 
563  TGeoMedium* medium = mgr.GetMedium(matname);
564  if (nullptr == medium) {
565  --unique_mat_id;
566  medium = new TGeoMedium(matname, unique_mat_id, mix);
567  medium->SetTitle("material");
568  medium->SetUniqueID(unique_mat_id);
569  }
570  }
571 }
572 
574 template <>
575 void Converter<DDLCompositeMaterial>::operator()(xml_h element) const {
576  cms::DDNamespace ns(_param<cms::DDParsingContext>());
577  xml_dim_t xmat(element);
578  string nam = ns.prepend(xmat.nameStr());
579 
580  TGeoManager& mgr = description.manager();
581  TGeoMaterial* mat = mgr.GetMaterial(nam.c_str());
582  if (nullptr == mat) {
583  const char* matname = nam.c_str();
584  double density = xmat.attr<double>(DD_CMU(density)) / (dd4hep::g / dd4hep::cm3);
585  xml_coll_t composites(xmat, DD_CMU(MaterialFraction));
586  TGeoMixture* mix = new TGeoMixture(nam.c_str(), composites.size(), density);
587 
588 #ifdef EDM_ML_DEBUG
589 
590  printout(ns.context()->debug_materials ? ALWAYS : DEBUG,
591  "DD4CMS",
592  "++ Converting material %-48s Density: %8.3f [g/cm3] ROOT: %8.3f [g/cm3]",
593  ('"' + nam + '"').c_str(),
594  density,
595  mix->GetDensity());
596 
597 #endif
598 
599  for (composites.reset(); composites; ++composites) {
600  xml_dim_t xfrac(composites);
601  xml_dim_t xfrac_mat(xfrac.child(DD_CMU(rMaterial)));
602  double fraction = xfrac.fraction();
603  string fracname = ns.realName(xfrac_mat.nameStr());
604 
605  TGeoMaterial* frac_mat = mgr.GetMaterial(fracname.c_str());
606  if (frac_mat == nullptr) // Try to find it within this namespace
607  frac_mat = mgr.GetMaterial(ns.prepend(fracname).c_str());
608  if (frac_mat) {
609  mix->AddElement(frac_mat, fraction);
610  continue;
611  }
612 
613 #ifdef EDM_ML_DEBUG
614 
615  printout(ns.context()->debug_materials ? ALWAYS : DEBUG,
616  "DD4CMS Warning",
617  "+++ Composite material \"%s\" [nor \"%s\"] not present! [delay resolution]",
618  fracname.c_str(),
619  ns.prepend(fracname).c_str());
620 
621 #endif
622 
623  ns.context()->unresolvedMaterials[nam].emplace_back(
624  cms::DDParsingContext::CompositeMaterial(ns.prepend(fracname), fraction));
625  }
626  mix->SetTemperature(ns.context()->description.stdConditions().temperature);
627  mix->SetPressure(ns.context()->description.stdConditions().pressure);
628  mix->SetRadLen(0e0);
630  TGeoMedium* medium = mgr.GetMedium(matname);
631  if (nullptr == medium) {
632  --unique_mat_id;
633  medium = new TGeoMedium(matname, unique_mat_id, mix);
634  medium->SetTitle("material");
635  medium->SetUniqueID(unique_mat_id);
636  }
637  }
638 }
639 
641 template <>
642 void Converter<DDLRotation>::operator()(xml_h element) const {
643  cms::DDParsingContext* context = _param<cms::DDParsingContext>();
644  cms::DDNamespace ns(context);
645  xml_dim_t xrot(element);
646  string nam = xrot.nameStr();
647  double thetaX = xrot.hasAttr(DD_CMU(thetaX)) ? ns.attr<double>(xrot, DD_CMU(thetaX)) : 0e0;
648  double phiX = xrot.hasAttr(DD_CMU(phiX)) ? ns.attr<double>(xrot, DD_CMU(phiX)) : 0e0;
649  double thetaY = xrot.hasAttr(DD_CMU(thetaY)) ? ns.attr<double>(xrot, DD_CMU(thetaY)) : 0e0;
650  double phiY = xrot.hasAttr(DD_CMU(phiY)) ? ns.attr<double>(xrot, DD_CMU(phiY)) : 0e0;
651  double thetaZ = xrot.hasAttr(DD_CMU(thetaZ)) ? ns.attr<double>(xrot, DD_CMU(thetaZ)) : 0e0;
652  double phiZ = xrot.hasAttr(DD_CMU(phiZ)) ? ns.attr<double>(xrot, DD_CMU(phiZ)) : 0e0;
653  Rotation3D rot = makeRotation3D(thetaX, phiX, thetaY, phiY, thetaZ, phiZ);
654 
655 #ifdef EDM_ML_DEBUG
656 
657  printout(context->debug_rotations ? ALWAYS : DEBUG,
658  "DD4CMS",
659  "+++ Adding rotation: %-32s: (theta/phi)[rad] X: %6.3f %6.3f Y: %6.3f %6.3f Z: %6.3f %6.3f",
660  ns.prepend(nam).c_str(),
661  thetaX,
662  phiX,
663  thetaY,
664  phiY,
665  thetaZ,
666  phiZ);
667 
668 #endif
669 
670  ns.addRotation(nam, rot);
671 }
672 
674 template <>
675 void Converter<DDLReflectionRotation>::operator()(xml_h element) const {
676  cms::DDParsingContext* context = _param<cms::DDParsingContext>();
677  cms::DDNamespace ns(context);
678  xml_dim_t xrot(element);
679  string name = xrot.nameStr();
680  double thetaX = xrot.hasAttr(DD_CMU(thetaX)) ? ns.attr<double>(xrot, DD_CMU(thetaX)) : 0e0;
681  double phiX = xrot.hasAttr(DD_CMU(phiX)) ? ns.attr<double>(xrot, DD_CMU(phiX)) : 0e0;
682  double thetaY = xrot.hasAttr(DD_CMU(thetaY)) ? ns.attr<double>(xrot, DD_CMU(thetaY)) : 0e0;
683  double phiY = xrot.hasAttr(DD_CMU(phiY)) ? ns.attr<double>(xrot, DD_CMU(phiY)) : 0e0;
684  double thetaZ = xrot.hasAttr(DD_CMU(thetaZ)) ? ns.attr<double>(xrot, DD_CMU(thetaZ)) : 0e0;
685  double phiZ = xrot.hasAttr(DD_CMU(phiZ)) ? ns.attr<double>(xrot, DD_CMU(phiZ)) : 0e0;
686 
687 #ifdef EDM_ML_DEBUG
688 
689  printout(context->debug_rotations ? ALWAYS : DEBUG,
690  "DD4CMS",
691  "+++ Adding reflection rotation: %-32s: (theta/phi)[rad] X: %6.3f %6.3f Y: %6.3f %6.3f Z: %6.3f %6.3f",
692  ns.prepend(name).c_str(),
693  thetaX,
694  phiX,
695  thetaY,
696  phiY,
697  thetaZ,
698  phiZ);
699 
700 #endif
701 
702  Rotation3D rot = makeRotReflect(thetaX, phiX, thetaY, phiY, thetaZ, phiZ);
703  ns.addRotation(name, rot);
704 }
705 
707 template <>
708 void Converter<DDLRotationSequence>::operator()(xml_h element) const {
709  cms::DDParsingContext* context = _param<cms::DDParsingContext>();
710  cms::DDNamespace ns(context);
711  xml_dim_t xrot(element);
712  string nam = xrot.nameStr();
713  Rotation3D rot;
714  xml_coll_t rotations(xrot, DD_CMU(RotationByAxis));
715  for (rotations.reset(); rotations; ++rotations) {
716  string axis = ns.attr<string>(rotations, DD_CMU(axis));
717  double angle = ns.attr<double>(rotations, _U(angle));
718  rot = makeRotation3D(rot, axis, angle);
719 
720 #ifdef EDM_ML_DEBUG
721 
722  printout(context->debug_rotations ? ALWAYS : DEBUG,
723  "DD4CMS",
724  "+ Adding rotation to: %-29s: (axis/angle)[rad] Axis: %s Angle: %6.3f",
725  nam.c_str(),
726  axis.c_str(),
727  angle);
728 
729 #endif
730  }
731  double xx, xy, xz;
732  double yx, yy, yz;
733  double zx, zy, zz;
734  rot.GetComponents(xx, xy, xz, yx, yy, yz, zx, zy, zz);
735 
736 #ifdef EDM_ML_DEBUG
737 
738  printout(context->debug_rotations ? ALWAYS : DEBUG,
739  "DD4CMS",
740  "+++ Adding rotation sequence: %-23s: %6.3f %6.3f %6.3f, %6.3f %6.3f %6.3f, %6.3f %6.3f %6.3f",
741  ns.prepend(nam).c_str(),
742  xx,
743  xy,
744  xz,
745  yx,
746  yy,
747  yz,
748  zx,
749  zy,
750  zz);
751 
752 #endif
753 
754  ns.addRotation(nam, rot);
755 }
756 
758 template <>
759 void Converter<DDLRotationByAxis>::operator()(xml_h element) const {
760  cms::DDParsingContext* context = _param<cms::DDParsingContext>();
761  cms::DDNamespace ns(context);
762  xml_dim_t xrot(element);
763  xml_dim_t par(xrot.parent());
764  if (xrot.hasAttr(_U(name))) {
765  string nam = xrot.nameStr();
766  string axis = ns.attr<string>(xrot, DD_CMU(axis));
767  double angle = ns.attr<double>(xrot, _U(angle));
768  Rotation3D rot;
769  rot = makeRotation3D(rot, axis, angle);
770 
771 #ifdef EDM_ML_DEBUG
772 
773  printout(context->debug_rotations ? ALWAYS : DEBUG,
774  "DD4CMS",
775  "+++ Adding rotation: %-32s: (axis/angle)[rad] Axis: %s Angle: %6.3f",
776  ns.prepend(nam).c_str(),
777  axis.c_str(),
778  angle);
779 
780 #endif
781 
782  ns.addRotation(nam, rot);
783  }
784 }
785 
787 template <>
788 void Converter<DDLLogicalPart>::operator()(xml_h element) const {
789  cms::DDNamespace ns(_param<cms::DDParsingContext>());
790  xml_dim_t e(element);
791  string sol = e.child(DD_CMU(rSolid)).attr<string>(_U(name));
792  string mat = e.child(DD_CMU(rMaterial)).attr<string>(_U(name));
793  string volName = ns.prepend(e.attr<string>(_U(name)));
794  Solid solid = ns.solid(sol);
795  Material material = ns.material(mat);
796 
797 #ifdef EDM_ML_DEBUG
798  Volume volume =
799 #endif
800 
801  ns.addVolume(Volume(volName, solid, material));
802 
803 #ifdef EDM_ML_DEBUG
804 
805  printout(ns.context()->debug_volumes ? ALWAYS : DEBUG,
806  "DD4CMS",
807  "+++ %s Volume: %-24s [%s] Shape: %-32s [%s] Material: %-40s [%s]",
808  e.tag().c_str(),
809  volName.c_str(),
810  volume.isValid() ? "VALID" : "INVALID",
811  sol.c_str(),
812  solid.isValid() ? "VALID" : "INVALID",
813  mat.c_str(),
814  material.isValid() ? "VALID" : "INVALID");
815 
816 #endif
817 }
818 
820 template <>
821 void Converter<DDLTransform3D>::operator()(xml_h element) const {
822  cms::DDNamespace ns(_param<cms::DDParsingContext>());
823  Transform3D* tr = _option<Transform3D>();
824  xml_dim_t e(element);
825  xml_dim_t translation = e.child(DD_CMU(Translation), false);
826  xml_dim_t rotation = e.child(DD_CMU(Rotation), false);
827  xml_dim_t refRotation = e.child(DD_CMU(rRotation), false);
828  xml_dim_t refReflectionRotation = e.child(DD_CMU(rReflectionRotation), false);
829  Position pos;
830  Rotation3D rot;
831 
832  if (translation.ptr()) {
833  double x = ns.attr<double>(translation, _U(x));
834  double y = ns.attr<double>(translation, _U(y));
835  double z = ns.attr<double>(translation, _U(z));
836  pos = Position(x, y, z);
837  }
838  if (rotation.ptr()) {
839  double x = ns.attr<double>(rotation, _U(x));
840  double y = ns.attr<double>(rotation, _U(y));
841  double z = ns.attr<double>(rotation, _U(z));
842  rot = RotationZYX(z, y, x);
843  } else if (refRotation.ptr()) {
844  string rotName = ns.prepend(refRotation.nameStr());
845  rot = ns.rotation(rotName);
846  } else if (refReflectionRotation.ptr()) {
847  string rotName = ns.prepend(refReflectionRotation.nameStr());
848  rot = ns.rotation(rotName);
849  }
850  *tr = Transform3D(rot, pos);
851 }
852 
854 template <>
855 void Converter<DDLPosPart>::operator()(xml_h element) const {
856  cms::DDNamespace ns(_param<cms::DDParsingContext>()); //, element, true );
857  xml_dim_t e(element);
858  int copy = e.attr<int>(DD_CMU(copyNumber));
859  string parentName = ns.prepend(ns.attr<string>(e.child(DD_CMU(rParent)), _U(name)));
860  string childName = ns.prepend(ns.attr<string>(e.child(DD_CMU(rChild)), _U(name)));
861  Volume parent = ns.volume(parentName, false);
862  Volume child = ns.volume(childName, false);
863 
864 #ifdef EDM_ML_DEBUG
865 
866  printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
867  "DD4CMS",
868  "+++ %s Parent: %-24s [%s] Child: %-32s [%s] copy:%d",
869  e.tag().c_str(),
870  parentName.c_str(),
871  parent.isValid() ? "VALID" : "INVALID",
872  childName.c_str(),
873  child.isValid() ? "VALID" : "INVALID",
874  copy);
875 
876 #endif
877 
878  if (!parent.isValid() && strchr(parentName.c_str(), NAMESPACE_SEP) == nullptr)
879  parentName = ns.prepend(parentName);
880  parent = ns.volume(parentName);
881 
882  if (!child.isValid() && strchr(childName.c_str(), NAMESPACE_SEP) == nullptr)
883  childName = ns.prepend(childName);
884  child = ns.volume(childName, false);
885 
886 #ifdef EDM_ML_DEBUG
887 
888  printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
889  "DD4CMS",
890  "+++ %s Parent: %-24s [%s] Child: %-32s [%s] copy:%d",
891  e.tag().c_str(),
892  parentName.c_str(),
893  parent.isValid() ? "VALID" : "INVALID",
894  childName.c_str(),
895  child.isValid() ? "VALID" : "INVALID",
896  copy);
897 
898 #endif
899 
901  if (child.isValid()) {
902  Transform3D transform;
903  Converter<DDLTransform3D>(description, param, &transform)(element);
904 
905  // FIXME: workaround for Reflection rotation
906  // copy from DDCore/src/Volumes.cpp to replace
907  // static PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, int id, TGeoMatrix* transform)
908  if (!parent) {
909  except("dd4hep", "Volume: Attempt to assign daughters to an invalid physical parent volume.");
910  }
911  if (!child) {
912  except("dd4hep", "Volume: Attempt to assign an invalid physical daughter volume.");
913  }
914  TGeoShape* shape = child->GetShape();
915  // Need to fix the daughter's BBox of assemblies, if the BBox was not calculated....
916  if (shape->IsA() == TGeoShapeAssembly::Class()) {
917  TGeoShapeAssembly* as = (TGeoShapeAssembly*)shape;
918  if (std::fabs(as->GetDX()) < numeric_limits<double>::epsilon() &&
919  std::fabs(as->GetDY()) < numeric_limits<double>::epsilon() &&
920  std::fabs(as->GetDZ()) < numeric_limits<double>::epsilon()) {
921  as->NeedsBBoxRecompute();
922  as->ComputeBBox();
923  }
924  }
925  TGeoNode* n;
926  TString nam_id = TString::Format("%s_%d", child->GetName(), copy);
927  n = static_cast<TGeoNode*>(parent->GetNode(nam_id));
928  if (n != nullptr) {
929  printout(ERROR, "PlacedVolume", "++ Attempt to add already exiting node %s", (const char*)nam_id);
930  }
931 
932  Rotation3D rot(transform.Rotation());
933  Translation3D trans(transform.Translation());
934  double x, y, z;
935  trans.GetComponents(x, y, z);
936  Position pos(x, y, z);
937  parent->AddNode(child, copy, createPlacement(rot, pos));
938 
939  n = static_cast<TGeoNode*>(parent->GetNode(nam_id));
940  n->TGeoNode::SetUserExtension(new PlacedVolume::Object());
941  pv = PlacedVolume(n);
942  }
943  if (!pv.isValid()) {
944  printout(ERROR,
945  "DD4CMS",
946  "+++ Placement FAILED! Parent:%s Child:%s Valid:%s",
947  parent.name(),
948  childName.c_str(),
949  yes_no(child.isValid()));
950  }
951 }
952 
954 template <>
955 void Converter<PartSelector>::operator()(xml_h element) const {
956  cms::DDNamespace ns(_param<cms::DDParsingContext>());
957  cms::DDParsingContext* const context = ns.context();
958  dd4hep::SpecParRegistry& registry = *context->description.extension<dd4hep::SpecParRegistry>();
959  xml_dim_t e(element);
960  xml_dim_t specPar = e.parent();
961  string specParName = specPar.attr<string>(_U(name));
962  string path = e.attr<string>(DD_CMU(path));
963 
964 #ifdef EDM_ML_DEBUG
965 
966  printout(ns.context()->debug_specpars ? ALWAYS : DEBUG,
967  "DD4CMS",
968  "+++ PartSelector for %s path: %s",
969  specParName.c_str(),
970  path.c_str());
971 
972 #endif
973 
974  size_t pos = std::string::npos;
975  if ((pos = path.find("//.*:")) != std::string::npos) {
976  path.erase(pos + 2, 3);
977  }
978  registry.specpars[specParName].paths.emplace_back(std::move(path));
979 }
980 
982 template <>
983 void Converter<Parameter>::operator()(xml_h element) const {
984  cms::DDNamespace ns(_param<cms::DDParsingContext>());
985  cms::DDParsingContext* const context = ns.context();
986  dd4hep::SpecParRegistry& registry = *context->description.extension<dd4hep::SpecParRegistry>();
987  xml_dim_t e(element);
988  xml_dim_t specPar = e.parent();
989  xml_dim_t specParSect = specPar.parent();
990  string specParName = specPar.attr<string>(_U(name));
991  string name = e.nameStr();
992  string value = e.attr<string>(DD_CMU(value));
993  bool eval = specParSect.hasAttr(_U(eval)) ? specParSect.attr<bool>(_U(eval)) : false;
994  eval = specPar.hasAttr(_U(eval)) ? specPar.attr<bool>(_U(eval)) : eval;
995  eval = e.hasAttr(_U(eval)) ? e.attr<bool>(_U(eval)) : eval;
996 
997  string type = eval ? "number" : "string";
998 
999 #ifdef EDM_ML_DEBUG
1000 
1001  printout(ns.context()->debug_specpars ? ALWAYS : DEBUG,
1002  "DD4CMS",
1003  "+++ Parameter for %s: %s value %s is a %s",
1004  specParName.c_str(),
1005  name.c_str(),
1006  value.c_str(),
1007  type.c_str());
1008 
1009 #endif
1010 
1011  size_t idx = value.find('[');
1012  if (idx == string::npos && type == "number") {
1013  registry.specpars[specParName].numpars[name].emplace_back(dd4hep::_toDouble(value));
1014  return;
1015  }
1016  if (idx == string::npos || type == "string") {
1017  registry.specpars[specParName].spars[name].emplace_back(std::move(value));
1018  return;
1019  }
1020 
1021  while (idx != string::npos) {
1022  ++idx;
1023  size_t idp = value.find(':', idx);
1024  size_t idq = value.find(']', idx);
1025  if (idp == string::npos || idp > idq)
1026  value.insert(idx, ns.name());
1027  else if (idp != string::npos && idp < idq)
1028  value[idp] = NAMESPACE_SEP;
1029  idx = value.find('[', idx);
1030  }
1031 
1032  string rep;
1033  string& v = value;
1034  size_t idq;
1035  for (idx = v.find('[', 0); idx != string::npos; idx = v.find('[', idx + 1)) {
1036  idq = v.find(']', idx + 1);
1037  rep = v.substr(idx + 1, idq - idx - 1);
1038  auto r = ns.context()->description.constants().find(rep);
1039  if (r != ns.context()->description.constants().end()) {
1040  rep = "(" + r->second->type + ")";
1041  v.replace(idx, idq - idx + 1, rep);
1042  }
1043  }
1044  registry.specpars[specParName].numpars[name].emplace_back(dd4hep::_toDouble(value));
1045 }
1046 
1047 template <typename TYPE>
1048 static void convert_boolean(cms::DDParsingContext* context, xml_h element) {
1049  cms::DDNamespace ns(context);
1050  xml_dim_t e(element);
1051  string nam = e.nameStr();
1052  string solidName[2];
1053  Solid solids[2];
1054  Solid boolean;
1055  int cnt = 0;
1056  if (e.hasChild(DD_CMU(rSolid))) {
1057  for (xml_coll_t c(element, DD_CMU(rSolid)); cnt < 2 && c; ++c, ++cnt) {
1058  solidName[cnt] = c.attr<string>(_U(name));
1059  solids[cnt] = ns.solid(c.attr<string>(_U(name)));
1060  }
1061  } else {
1062  solidName[0] = e.attr<string>(DD_CMU(firstSolid));
1063  if ((solids[0] = ns.solid(e.attr<string>(DD_CMU(firstSolid)))).isValid())
1064  ++cnt;
1065  solidName[1] = e.attr<string>(DD_CMU(secondSolid));
1066  if ((solids[1] = ns.solid(e.attr<string>(DD_CMU(secondSolid)))).isValid())
1067  ++cnt;
1068  }
1069  if (cnt != 2) {
1070  except("DD4CMS", "+++ Failed to create boolean solid %s. Found only %d parts.", nam.c_str(), cnt);
1071  }
1072 
1073 #ifdef EDM_ML_DEBUG
1074 
1075  printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
1076  "DD4CMS",
1077  "+++ BooleanSolid: %s Left: %-32s Right: %-32s",
1078  nam.c_str(),
1079  ((solids[0].ptr() == nullptr) ? solidName[0].c_str() : solids[0]->GetName()),
1080  ((solids[1].ptr() == nullptr) ? solidName[1].c_str() : solids[1]->GetName()));
1081 
1082 #endif
1083 
1084  if (solids[0].isValid() && solids[1].isValid()) {
1085  Transform3D trafo;
1086  Converter<DDLTransform3D>(context->description, context, &trafo)(element);
1087  boolean = TYPE(solids[0], solids[1], trafo);
1088  } else {
1089  // Register it for later processing
1090  Transform3D trafo;
1091  Converter<DDLTransform3D>(context->description, context, &trafo)(element);
1092  ns.context()->unresolvedShapes.emplace(nam,
1093  DDParsingContext::BooleanShape<TYPE>(solidName[0], solidName[1], trafo));
1094  }
1095  if (!boolean.isValid()) {
1096  // Delay processing the shape
1097  ns.context()->shapes.emplace(nam, dd4hep::Solid(nullptr));
1098  } else
1099  ns.addSolid(nam, boolean);
1100 }
1101 
1103 template <>
1104 void Converter<DDLUnionSolid>::operator()(xml_h element) const {
1105  convert_boolean<UnionSolid>(_param<cms::DDParsingContext>(), element);
1106 }
1107 
1109 template <>
1110 void Converter<DDLSubtractionSolid>::operator()(xml_h element) const {
1111  convert_boolean<SubtractionSolid>(_param<cms::DDParsingContext>(), element);
1112 }
1113 
1115 template <>
1116 void Converter<DDLIntersectionSolid>::operator()(xml_h element) const {
1117  convert_boolean<IntersectionSolid>(_param<cms::DDParsingContext>(), element);
1118 }
1119 
1121 template <>
1122 void Converter<DDLPolycone>::operator()(xml_h element) const {
1123  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1124  xml_dim_t e(element);
1125  string nam = e.nameStr();
1126  double startPhi = ns.attr<double>(e, DD_CMU(startPhi));
1127  double deltaPhi = ns.attr<double>(e, DD_CMU(deltaPhi));
1128  vector<double> z, rmin, rmax, r;
1129 
1130  for (xml_coll_t rzpoint(element, DD_CMU(RZPoint)); rzpoint; ++rzpoint) {
1131  z.emplace_back(ns.attr<double>(rzpoint, _U(z)));
1132  r.emplace_back(ns.attr<double>(rzpoint, _U(r)));
1133  }
1134  if (z.empty()) {
1135  for (xml_coll_t zplane(element, DD_CMU(ZSection)); zplane; ++zplane) {
1136  rmin.emplace_back(ns.attr<double>(zplane, DD_CMU(rMin)));
1137  rmax.emplace_back(ns.attr<double>(zplane, DD_CMU(rMax)));
1138  z.emplace_back(ns.attr<double>(zplane, _U(z)));
1139  }
1140 
1141 #ifdef EDM_ML_DEBUG
1142 
1143  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1144  "DD4CMS",
1145  "+ Polycone: startPhi=%10.3f [rad] deltaPhi=%10.3f [rad] %4ld z-planes",
1146  startPhi,
1147  deltaPhi,
1148  z.size());
1149 
1150 #endif
1151 
1152  ns.addSolid(nam, Polycone(startPhi, deltaPhi, rmin, rmax, z));
1153  } else {
1154 #ifdef EDM_ML_DEBUG
1155 
1156  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1157  "DD4CMS",
1158  "+ Polycone: startPhi=%10.3f [rad] deltaPhi=%10.3f [rad] %4ld z-planes and %4ld radii",
1159  startPhi,
1160  deltaPhi,
1161  z.size(),
1162  r.size());
1163 
1164 #endif
1165 
1166  ns.addSolid(nam, Polycone(startPhi, deltaPhi, r, z));
1167  }
1168 }
1169 
1171 template <>
1172 void Converter<DDLExtrudedPolygon>::operator()(xml_h element) const {
1173  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1174  xml_dim_t e(element);
1175  string nam = e.nameStr();
1176  vector<double> pt_x, pt_y, sec_x, sec_y, sec_z, sec_scale;
1177 
1178  for (xml_coll_t sec(element, DD_CMU(ZXYSection)); sec; ++sec) {
1179  sec_z.emplace_back(ns.attr<double>(sec, _U(z)));
1180  sec_x.emplace_back(ns.attr<double>(sec, _U(x)));
1181  sec_y.emplace_back(ns.attr<double>(sec, _U(y)));
1182  sec_scale.emplace_back(ns.attr<double>(sec, DD_CMU(scale), 1.0));
1183  }
1184  for (xml_coll_t pt(element, DD_CMU(XYPoint)); pt; ++pt) {
1185  pt_x.emplace_back(ns.attr<double>(pt, _U(x)));
1186  pt_y.emplace_back(ns.attr<double>(pt, _U(y)));
1187  }
1188 
1189 #ifdef EDM_ML_DEBUG
1190 
1191  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1192  "DD4CMS",
1193  "+ ExtrudedPolygon: %4ld points %4ld zxy sections",
1194  pt_x.size(),
1195  sec_z.size());
1196 
1197 #endif
1198 
1199  ns.addSolid(nam, ExtrudedPolygon(pt_x, pt_y, sec_z, sec_x, sec_y, sec_scale));
1200 }
1201 
1203 template <>
1204 void Converter<DDLPolyhedra>::operator()(xml_h element) const {
1205  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1206  xml_dim_t e(element);
1207  string nam = e.nameStr();
1208  double numSide = ns.attr<int>(e, DD_CMU(numSide));
1209  double startPhi = ns.attr<double>(e, DD_CMU(startPhi));
1210  double deltaPhi = ns.attr<double>(e, DD_CMU(deltaPhi));
1211  vector<double> z, rmin, rmax;
1212 
1213  for (xml_coll_t zplane(element, DD_CMU(RZPoint)); zplane; ++zplane) {
1214  rmin.emplace_back(0.0);
1215  rmax.emplace_back(ns.attr<double>(zplane, _U(r)));
1216  z.emplace_back(ns.attr<double>(zplane, _U(z)));
1217  }
1218  for (xml_coll_t zplane(element, DD_CMU(ZSection)); zplane; ++zplane) {
1219  rmin.emplace_back(ns.attr<double>(zplane, DD_CMU(rMin)));
1220  rmax.emplace_back(ns.attr<double>(zplane, DD_CMU(rMax)));
1221  z.emplace_back(ns.attr<double>(zplane, _U(z)));
1222  }
1223 
1224 #ifdef EDM_ML_DEBUG
1225 
1226  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1227  "DD4CMS",
1228  "+ Polyhedra:startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] %4d sides %4ld z-planes",
1229  startPhi,
1230  deltaPhi,
1231  numSide,
1232  z.size());
1233 
1234 #endif
1235 
1236  ns.addSolid(nam, Polyhedra(numSide, startPhi, deltaPhi, z, rmin, rmax));
1237 }
1238 
1240 template <>
1241 void Converter<DDLSphere>::operator()(xml_h element) const {
1242  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1243  xml_dim_t e(element);
1244  string nam = e.nameStr();
1245  double rinner = ns.attr<double>(e, DD_CMU(innerRadius));
1246  double router = ns.attr<double>(e, DD_CMU(outerRadius));
1247  double startPhi = ns.attr<double>(e, DD_CMU(startPhi));
1248  double deltaPhi = ns.attr<double>(e, DD_CMU(deltaPhi));
1249  double startTheta = ns.attr<double>(e, DD_CMU(startTheta));
1250  double deltaTheta = ns.attr<double>(e, DD_CMU(deltaTheta));
1251 
1252 #ifdef EDM_ML_DEBUG
1253 
1254  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1255  "DD4CMS",
1256  "+ Sphere: r_inner=%8.3f [cm] r_outer=%8.3f [cm]"
1257  " startPhi=%8.3f [rad] deltaPhi=%8.3f startTheta=%8.3f delteTheta=%8.3f [rad]",
1258  rinner / dd4hep::cm,
1259  router / dd4hep::cm,
1260  startPhi,
1261  deltaPhi,
1262  startTheta,
1263  deltaTheta);
1264 
1265 #endif
1266 
1267  ns.addSolid(nam, Sphere(rinner, router, startTheta, deltaTheta, startPhi, deltaPhi));
1268 }
1269 
1271 template <>
1272 void Converter<DDLTorus>::operator()(xml_h element) const {
1273  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1274  xml_dim_t e(element);
1275  string nam = e.nameStr();
1276  double r = ns.attr<double>(e, DD_CMU(torusRadius));
1277  double rinner = ns.attr<double>(e, DD_CMU(innerRadius));
1278  double router = ns.attr<double>(e, DD_CMU(outerRadius));
1279  double startPhi = ns.attr<double>(e, DD_CMU(startPhi));
1280  double deltaPhi = ns.attr<double>(e, DD_CMU(deltaPhi));
1281 
1282 #ifdef EDM_ML_DEBUG
1283 
1284  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1285  "DD4CMS",
1286  "+ Torus: r=%10.3f [cm] r_inner=%10.3f [cm] r_outer=%10.3f [cm]"
1287  " startPhi=%10.3f [rad] deltaPhi=%10.3f [rad]",
1288  r / dd4hep::cm,
1289  rinner / dd4hep::cm,
1290  router / dd4hep::cm,
1291  startPhi,
1292  deltaPhi);
1293 
1294 #endif
1295 
1296  ns.addSolid(nam, Torus(r, rinner, router, startPhi, deltaPhi));
1297 }
1298 
1300 template <>
1301 void Converter<DDLPseudoTrap>::operator()(xml_h element) const {
1302  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1303  xml_dim_t e(element);
1304  string nam = e.nameStr();
1305  double dx1 = ns.attr<double>(e, DD_CMU(dx1));
1306  double dy1 = ns.attr<double>(e, DD_CMU(dy1));
1307  double dx2 = ns.attr<double>(e, DD_CMU(dx2));
1308  double dy2 = ns.attr<double>(e, DD_CMU(dy2));
1309  double dz = ns.attr<double>(e, _U(dz));
1310  double r = ns.attr<double>(e, _U(radius));
1311  bool atMinusZ = ns.attr<bool>(e, DD_CMU(atMinusZ));
1312 
1313 #ifdef EDM_ML_DEBUG
1314 
1315  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1316  "DD4CMS",
1317  "+ Pseudotrap: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2=%.3f dy2=%.3f radius:%.3f atMinusZ:%s",
1318  dz / dd4hep::cm,
1319  dx1 / dd4hep::cm,
1320  dy1 / dd4hep::cm,
1321  dx2 / dd4hep::cm,
1322  dy2 / dd4hep::cm,
1323  r / dd4hep::cm,
1324  yes_no(atMinusZ));
1325 
1326 #endif
1327 
1328  ns.addSolid(nam, PseudoTrap(dx1, dx2, dy1, dy2, dz, r, atMinusZ));
1329 }
1330 
1332 template <>
1333 void Converter<DDLTrapezoid>::operator()(xml_h element) const {
1334  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1335  xml_dim_t e(element);
1336  string nam = e.nameStr();
1337  double dz = ns.attr<double>(e, _U(dz));
1338  double alp1 = ns.attr<double>(e, DD_CMU(alp1));
1339  double bl1 = ns.attr<double>(e, DD_CMU(bl1));
1340  double tl1 = ns.attr<double>(e, DD_CMU(tl1));
1341  double h1 = ns.attr<double>(e, DD_CMU(h1));
1342  double alp2 = ns.attr<double>(e, DD_CMU(alp2));
1343  double bl2 = ns.attr<double>(e, DD_CMU(bl2));
1344  double tl2 = ns.attr<double>(e, DD_CMU(tl2));
1345  double h2 = ns.attr<double>(e, DD_CMU(h2));
1346  double phi = ns.attr<double>(e, _U(phi), 0.0);
1347  double theta = ns.attr<double>(e, _U(theta), 0.0);
1348 
1349 #ifdef EDM_ML_DEBUG
1350 
1351  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1352  "DD4CMS",
1353  "+ Trapezoid: dz=%10.3f [cm] alp1:%.3f bl1=%.3f tl1=%.3f alp2=%.3f bl2=%.3f tl2=%.3f h2=%.3f phi=%.3f "
1354  "theta=%.3f",
1355  dz / dd4hep::cm,
1356  alp1,
1357  bl1 / dd4hep::cm,
1358  tl1 / dd4hep::cm,
1359  h1 / dd4hep::cm,
1360  alp2,
1361  bl2 / dd4hep::cm,
1362  tl2 / dd4hep::cm,
1363  h2 / dd4hep::cm,
1364  phi,
1365  theta);
1366 
1367 #endif
1368 
1369  ns.addSolid(nam, Trap(dz, theta, phi, h1, bl1, tl1, alp1, h2, bl2, tl2, alp2));
1370 }
1371 
1373 template <>
1374 void Converter<DDLTrd1>::operator()(xml_h element) const {
1375  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1376  xml_dim_t e(element);
1377  string nam = e.nameStr();
1378  double dx1 = ns.attr<double>(e, DD_CMU(dx1));
1379  double dy1 = ns.attr<double>(e, DD_CMU(dy1));
1380  double dx2 = ns.attr<double>(e, DD_CMU(dx2), 0.0);
1381  double dy2 = ns.attr<double>(e, DD_CMU(dy2), dy1);
1382  double dz = ns.attr<double>(e, DD_CMU(dz));
1383  if (dy1 == dy2) {
1384 #ifdef EDM_ML_DEBUG
1385 
1386  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1387  "DD4CMS",
1388  "+ Trd1: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1389  dz / dd4hep::cm,
1390  dx1 / dd4hep::cm,
1391  dy1 / dd4hep::cm,
1392  dx2 / dd4hep::cm,
1393  dy2 / dd4hep::cm);
1394 
1395 #endif
1396 
1397  ns.addSolid(nam, Trd1(dx1, dx2, dy1, dz));
1398  } else {
1399 #ifdef EDM_ML_DEBUG
1400 
1401  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1402  "DD4CMS",
1403  "+ Trd1(which is actually Trd2): dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1404  dz / dd4hep::cm,
1405  dx1 / dd4hep::cm,
1406  dy1 / dd4hep::cm,
1407  dx2 / dd4hep::cm,
1408  dy2 / dd4hep::cm);
1409 
1410 #endif
1411 
1412  ns.addSolid(nam, Trd2(dx1, dx2, dy1, dy2, dz));
1413  }
1414 }
1415 
1417 template <>
1418 void Converter<DDLTrd2>::operator()(xml_h element) const {
1419  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1420  xml_dim_t e(element);
1421  string nam = e.nameStr();
1422  double dx1 = ns.attr<double>(e, DD_CMU(dx1));
1423  double dy1 = ns.attr<double>(e, DD_CMU(dy1));
1424  double dx2 = ns.attr<double>(e, DD_CMU(dx2), 0.0);
1425  double dy2 = ns.attr<double>(e, DD_CMU(dy2), dy1);
1426  double dz = ns.attr<double>(e, DD_CMU(dz));
1427 
1428 #ifdef EDM_ML_DEBUG
1429 
1430  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1431  "DD4CMS",
1432  "+ Trd1: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1433  dz / dd4hep::cm,
1434  dx1 / dd4hep::cm,
1435  dy1 / dd4hep::cm,
1436  dx2 / dd4hep::cm,
1437  dy2 / dd4hep::cm);
1438 
1439 #endif
1440 
1441  ns.addSolid(nam, Trd2(dx1, dx2, dy1, dy2, dz));
1442 }
1443 
1445 template <>
1446 void Converter<DDLTubs>::operator()(xml_h element) const {
1447  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1448  xml_dim_t e(element);
1449  string nam = e.nameStr();
1450  double dz = ns.attr<double>(e, DD_CMU(dz));
1451  double rmin = ns.attr<double>(e, DD_CMU(rMin));
1452  double rmax = ns.attr<double>(e, DD_CMU(rMax));
1453  double startPhi = ns.attr<double>(e, DD_CMU(startPhi), 0.0);
1454  double deltaPhi = ns.attr<double>(e, DD_CMU(deltaPhi), 2 * M_PI);
1455 
1456 #ifdef EDM_ML_DEBUG
1457 
1458  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1459  "DD4CMS",
1460  "+ Tubs: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
1461  " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]",
1462  dz / dd4hep::cm,
1463  rmin / dd4hep::cm,
1464  rmax / dd4hep::cm,
1465  startPhi,
1466  deltaPhi);
1467 
1468 #endif
1469 
1470  ns.addSolid(nam, Tube(rmin, rmax, dz, startPhi, startPhi + deltaPhi));
1471 }
1472 
1474 template <>
1475 void Converter<DDLCutTubs>::operator()(xml_h element) const {
1476  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1477  xml_dim_t e(element);
1478  string nam = e.nameStr();
1479  double dz = ns.attr<double>(e, DD_CMU(dz));
1480  double rmin = ns.attr<double>(e, DD_CMU(rMin));
1481  double rmax = ns.attr<double>(e, DD_CMU(rMax));
1482  double startPhi = ns.attr<double>(e, DD_CMU(startPhi));
1483  double deltaPhi = ns.attr<double>(e, DD_CMU(deltaPhi));
1484  double lx = ns.attr<double>(e, DD_CMU(lx));
1485  double ly = ns.attr<double>(e, DD_CMU(ly));
1486  double lz = ns.attr<double>(e, DD_CMU(lz));
1487  double tx = ns.attr<double>(e, DD_CMU(tx));
1488  double ty = ns.attr<double>(e, DD_CMU(ty));
1489  double tz = ns.attr<double>(e, DD_CMU(tz));
1490 
1491 #ifdef EDM_ML_DEBUG
1492 
1493  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1494  "DD4CMS",
1495  "+ CutTube: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
1496  " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]...",
1497  dz / dd4hep::cm,
1498  rmin / dd4hep::cm,
1499  rmax / dd4hep::cm,
1500  startPhi,
1501  deltaPhi);
1502 
1503 #endif
1504 
1505  ns.addSolid(nam, CutTube(rmin, rmax, dz, startPhi, startPhi + deltaPhi, lx, ly, lz, tx, ty, tz));
1506 }
1507 
1509 template <>
1510 void Converter<DDLTruncTubs>::operator()(xml_h element) const {
1511  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1512  xml_dim_t e(element);
1513  string nam = e.nameStr();
1514  double zhalf = ns.attr<double>(e, DD_CMU(zHalf));
1515  double rmin = ns.attr<double>(e, DD_CMU(rMin));
1516  double rmax = ns.attr<double>(e, DD_CMU(rMax));
1517  double startPhi = ns.attr<double>(e, DD_CMU(startPhi));
1518  double deltaPhi = ns.attr<double>(e, DD_CMU(deltaPhi));
1519  double cutAtStart = ns.attr<double>(e, DD_CMU(cutAtStart));
1520  double cutAtDelta = ns.attr<double>(e, DD_CMU(cutAtDelta));
1521  bool cutInside = ns.attr<bool>(e, DD_CMU(cutInside));
1522 
1523 #ifdef EDM_ML_DEBUG
1524 
1525  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1526  "DD4CMS",
1527  "+ TruncTube:zHalf=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
1528  " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] atStart=%8.3f [cm] atDelta=%8.3f [cm] inside:%s",
1529  zhalf / dd4hep::cm,
1530  rmin / dd4hep::cm,
1531  rmax / dd4hep::cm,
1532  startPhi,
1533  deltaPhi,
1534  cutAtStart / dd4hep::cm,
1535  cutAtDelta / dd4hep::cm,
1536  yes_no(cutInside));
1537 
1538 #endif
1539 
1540  ns.addSolid(nam, TruncatedTube(zhalf, rmin, rmax, startPhi, deltaPhi, cutAtStart, cutAtDelta, cutInside));
1541 }
1542 
1544 template <>
1545 void Converter<DDLEllipticalTube>::operator()(xml_h element) const {
1546  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1547  xml_dim_t e(element);
1548  string nam = e.nameStr();
1549  double dx = ns.attr<double>(e, DD_CMU(xSemiAxis));
1550  double dy = ns.attr<double>(e, DD_CMU(ySemiAxis));
1551  double dz = ns.attr<double>(e, DD_CMU(zHeight));
1552 
1553 #ifdef EDM_ML_DEBUG
1554 
1555  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1556  "DD4CMS",
1557  "+ EllipticalTube xSemiAxis=%8.3f [cm] ySemiAxis=%8.3f [cm] zHeight=%8.3f [cm]",
1558  dx / dd4hep::cm,
1559  dy / dd4hep::cm,
1560  dz / dd4hep::cm);
1561 
1562 #endif
1563 
1564  ns.addSolid(nam, EllipticalTube(dx, dy, dz));
1565 }
1566 
1568 template <>
1569 void Converter<DDLCone>::operator()(xml_h element) const {
1570  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1571  xml_dim_t e(element);
1572  string nam = e.nameStr();
1573  double dz = ns.attr<double>(e, DD_CMU(dz));
1574  double rmin1 = ns.attr<double>(e, DD_CMU(rMin1));
1575  double rmin2 = ns.attr<double>(e, DD_CMU(rMin2));
1576  double rmax1 = ns.attr<double>(e, DD_CMU(rMax1));
1577  double rmax2 = ns.attr<double>(e, DD_CMU(rMax2));
1578  double startPhi = ns.attr<double>(e, DD_CMU(startPhi));
1579  double deltaPhi = ns.attr<double>(e, DD_CMU(deltaPhi));
1580  double phi2 = startPhi + deltaPhi;
1581 
1582 #ifdef EDM_ML_DEBUG
1583 
1584  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1585  "DD4CMS",
1586  "+ Cone: dz=%8.3f [cm]"
1587  " rmin1=%8.3f [cm] rmax1=%8.3f [cm]"
1588  " rmin2=%8.3f [cm] rmax2=%8.3f [cm]"
1589  " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]",
1590  dz / dd4hep::cm,
1591  rmin1 / dd4hep::cm,
1592  rmax1 / dd4hep::cm,
1593  rmin2 / dd4hep::cm,
1594  rmax2 / dd4hep::cm,
1595  startPhi,
1596  deltaPhi);
1597 
1598 #endif
1599 
1600  ns.addSolid(nam, ConeSegment(dz, rmin1, rmax1, rmin2, rmax2, startPhi, phi2));
1601 }
1602 
1604 template <>
1605 void Converter<DDLShapeless>::operator()(xml_h element) const {
1606  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1607  xml_dim_t e(element);
1608  string nam = e.nameStr();
1609 
1610 #ifdef EDM_ML_DEBUG
1611 
1612  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1613  "DD4CMS",
1614  "+ Shapeless: THIS ONE CAN ONLY BE USED AT THE VOLUME LEVEL -> Assembly%s",
1615  nam.c_str());
1616 
1617 #endif
1618 
1619  ns.addSolid(nam, Box(1, 1, 1));
1620 }
1621 
1623 template <>
1624 void Converter<DDLBox>::operator()(xml_h element) const {
1625  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1626  xml_dim_t e(element);
1627  string nam = e.nameStr();
1628  double dx = ns.attr<double>(e, DD_CMU(dx));
1629  double dy = ns.attr<double>(e, DD_CMU(dy));
1630  double dz = ns.attr<double>(e, DD_CMU(dz));
1631 
1632 #ifdef EDM_ML_DEBUG
1633 
1634  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1635  "DD4CMS",
1636  "+ Box: dx=%10.3f [cm] dy=%10.3f [cm] dz=%10.3f [cm]",
1637  dx / dd4hep::cm,
1638  dy / dd4hep::cm,
1639  dz / dd4hep::cm);
1640 
1641 #endif
1642 
1643  ns.addSolid(nam, Box(dx, dy, dz));
1644 }
1645 
1647 template <>
1648 void Converter<include_load>::operator()(xml_h element) const {
1649  string fname = element.attr<string>(_U(ref));
1651  xml::Document doc;
1652  doc = xml::DocumentHandler().load(fp.fullPath());
1653 
1654 #ifdef EDM_ML_DEBUG
1655 
1656  printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS : DEBUG,
1657  "DD4CMS",
1658  "+++ Processing the CMS detector description %s",
1659  fname.c_str());
1660 
1661 #endif
1662 
1663  _option<DDRegistry>()->includes.emplace_back(doc);
1664 }
1665 
1667 template <>
1668 void Converter<include_unload>::operator()(xml_h element) const {
1669  string fname = xml::DocumentHandler::system_path(element);
1670  xml::DocumentHolder(xml_elt_t(element).document()).assign(nullptr);
1671 
1672 #ifdef EDM_ML_DEBUG
1673 
1674  printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS : DEBUG,
1675  "DD4CMS",
1676  "+++ Finished processing %s",
1677  fname.c_str());
1678 #endif
1679 }
1680 
1682 template <>
1683 void Converter<include_constants>::operator()(xml_h element) const {
1684  xml_coll_t(element, DD_CMU(ConstantsSection)).for_each(Converter<ConstantsSection>(description, param, optional));
1685 }
1686 
1687 namespace {
1688 
1689  // The meaning of the axis index is the following:
1690  // for all volumes having shapes like box, trd1, trd2, trap, gtra or para - 1,2,3 means X,Y,Z;
1691  // for tube, tubs, cone, cons - 1 means Rxy, 2 means phi and 3 means Z;
1692  // for pcon and pgon - 2 means phi and 3 means Z;
1693  // for spheres 1 means R and 2 means phi.
1694 
1695  enum class DDAxes { x = 1, y = 2, z = 3, rho = 1, phi = 2, undefined };
1696  const std::map<std::string, DDAxes> axesmap{{"x", DDAxes::x},
1697  {"y", DDAxes::y},
1698  {"z", DDAxes::z},
1699  {"rho", DDAxes::rho},
1700  {"phi", DDAxes::phi},
1701  {"undefined", DDAxes::undefined}};
1702 } // namespace
1703 
1705 template <>
1706 void Converter<DDLDivision>::operator()(xml_h element) const {
1707  cms::DDNamespace ns(_param<cms::DDParsingContext>(), element);
1708  xml_dim_t e(element);
1709  string childName = e.nameStr();
1710  if (strchr(childName.c_str(), NAMESPACE_SEP) == nullptr)
1711  childName = ns.prepend(childName);
1712 
1713  string parentName = ns.attr<string>(e, DD_CMU(parent));
1714  if (strchr(parentName.c_str(), NAMESPACE_SEP) == nullptr)
1715  parentName = ns.prepend(parentName);
1716  string axis = ns.attr<string>(e, DD_CMU(axis));
1717 
1718  // If you divide a tube of 360 degrees the offset displaces
1719  // the starting angle, but you still fill the 360 degrees
1720  double offset = e.hasAttr(DD_CMU(offset)) ? ns.attr<double>(e, DD_CMU(offset)) : 0e0;
1721  double width = e.hasAttr(DD_CMU(width)) ? ns.attr<double>(e, DD_CMU(width)) : 0e0;
1722  int nReplicas = e.hasAttr(DD_CMU(nReplicas)) ? ns.attr<int>(e, DD_CMU(nReplicas)) : 0;
1723 
1724 #ifdef EDM_ML_DEBUG
1725 
1726  printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
1727  "DD4CMS",
1728  "+++ Start executing Division of %s along %s (%d) with offset %6.3f and %6.3f to produce %s....",
1729  parentName.c_str(),
1730  axis.c_str(),
1731  axesmap.at(axis),
1732  offset,
1733  width,
1734  childName.c_str());
1735 
1736 #endif
1737 
1738  Volume parent = ns.volume(parentName);
1739 
1740  const TGeoShape* shape = parent.solid();
1741  TClass* cl = shape->IsA();
1742  if (cl == TGeoTubeSeg::Class()) {
1743  const TGeoTubeSeg* sh = (const TGeoTubeSeg*)shape;
1744  double widthInDeg = convertRadToDeg(width);
1745  double startInDeg = convertRadToDeg(offset);
1746  int numCopies = (int)((sh->GetPhi2() - sh->GetPhi1()) / widthInDeg);
1747 
1748 #ifdef EDM_ML_DEBUG
1749 
1750  printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
1751  "DD4CMS",
1752  "+++ ...divide %s along %s (%d) with offset %6.3f deg and %6.3f deg to produce %d copies",
1753  parent.solid().type(),
1754  axis.c_str(),
1755  axesmap.at(axis),
1756  startInDeg,
1757  widthInDeg,
1758  numCopies);
1759 
1760 #endif
1761 
1762  Volume child = parent.divide(childName, static_cast<int>(axesmap.at(axis)), numCopies, startInDeg, widthInDeg);
1763 
1764  ns.context()->volumes[childName] = child;
1765 
1766 #ifdef EDM_ML_DEBUG
1767 
1768  printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
1769  "DD4CMS",
1770  "+++ %s Parent: %-24s [%s] Child: %-32s [%s] is multivolume [%s]",
1771  e.tag().c_str(),
1772  parentName.c_str(),
1773  parent.isValid() ? "VALID" : "INVALID",
1774  child.name(),
1775  child.isValid() ? "VALID" : "INVALID",
1776  child->IsVolumeMulti() ? "YES" : "NO");
1777 #endif
1778 
1779  } else if (cl == TGeoTrd1::Class()) {
1780  double dy = static_cast<const TGeoTrd1*>(shape)->GetDy();
1781 
1782 #ifdef EDM_ML_DEBUG
1783 
1784  printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
1785  "DD4CMS",
1786  "+++ ...divide %s along %s (%d) with offset %6.3f cm and %6.3f cm to produce %d copies in %6.3f",
1787  parent.solid().type(),
1788  axis.c_str(),
1789  axesmap.at(axis),
1790  -dy + offset + width,
1791  width,
1792  nReplicas,
1793  dy);
1794 
1795 #endif
1796 
1797  Volume child = parent.divide(childName, static_cast<int>(axesmap.at(axis)), nReplicas, -dy + offset + width, width);
1798 
1799  ns.context()->volumes[childName] = child;
1800 
1801 #ifdef EDM_ML_DEBUG
1802 
1803  printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
1804  "DD4CMS",
1805  "+++ %s Parent: %-24s [%s] Child: %-32s [%s] is multivolume [%s]",
1806  e.tag().c_str(),
1807  parentName.c_str(),
1808  parent.isValid() ? "VALID" : "INVALID",
1809  child.name(),
1810  child.isValid() ? "VALID" : "INVALID",
1811  child->IsVolumeMulti() ? "YES" : "NO");
1812 
1813 #endif
1814 
1815  } else {
1816  printout(ERROR, "DD4CMS", "++ FAILED Division of a %s is not implemented yet!", parent.solid().type());
1817  }
1818 }
1819 
1821 template <>
1822 void Converter<DDLAlgorithm>::operator()(xml_h element) const {
1823  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1824  xml_dim_t e(element);
1825  string name = e.nameStr();
1826  size_t idx;
1827  string type = "DDCMS_" + ns.realName(name);
1828  while ((idx = type.find(NAMESPACE_SEP)) != string::npos)
1829  type[idx] = '_';
1830 
1831 #ifdef EDM_ML_DEBUG
1832 
1833  printout(
1834  ns.context()->debug_algorithms ? ALWAYS : DEBUG, "DD4CMS", "+++ Start executing algorithm %s....", type.c_str());
1835 
1836 #endif
1837 
1838  long ret = PluginService::Create<long>(type, &description, ns.context(), &element);
1839  if (ret == s_executed) {
1840 #ifdef EDM_ML_DEBUG
1841 
1842  printout(ns.context()->debug_algorithms ? ALWAYS : DEBUG,
1843 
1844  "DD4CMS",
1845  "+++ Executed algorithm: %08lX = %s",
1846  ret,
1847  name.c_str());
1848 
1849 #endif
1850  return;
1851  }
1852  printout(ERROR, "DD4CMS", "++ FAILED NOT ADDING SUBDETECTOR %08lX = %s", ret, name.c_str());
1853 }
1854 
1855 template <class InputIt, class ForwardIt, class BinOp>
1856 void for_each_token(InputIt first, InputIt last, ForwardIt s_first, ForwardIt s_last, BinOp binary_op) {
1857  while (first != last) {
1858  const auto pos = std::find_first_of(first, last, s_first, s_last);
1859  binary_op(first, pos);
1860  if (pos == last)
1861  break;
1862  first = std::next(pos);
1863  }
1864 }
1865 
1866 namespace {
1867 
1868  std::vector<string> splitString(const string& str, const string& delims = ",") {
1869  std::vector<string> output;
1870 
1871  for_each_token(cbegin(str), cend(str), cbegin(delims), cend(delims), [&output](auto first, auto second) {
1872  if (first != second) {
1873  if (string(first, second).front() == '[' && string(first, second).back() == ']') {
1874  first++;
1875  second--;
1876  }
1877  output.emplace_back(string(first, second));
1878  }
1879  });
1880  return output;
1881  }
1882 
1883  std::vector<double> splitNumeric(const string& str, const string& delims = ",") {
1884  std::vector<double> output;
1885 
1886  for_each_token(cbegin(str), cend(str), cbegin(delims), cend(delims), [&output](auto first, auto second) {
1887  if (first != second) {
1888  if (string(first, second).front() == '[' && string(first, second).back() == ']') {
1889  first++;
1890  second--;
1891  }
1892  output.emplace_back(dd4hep::_toDouble(string(first, second)));
1893  }
1894  });
1895  return output;
1896  }
1897 } // namespace
1898 
1901 template <>
1902 void Converter<DDLVector>::operator()(xml_h element) const {
1903  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1904  cms::DDParsingContext* const context = ns.context();
1905  DDVectorsMap* registry = context->description.extension<DDVectorsMap>();
1906  xml_dim_t e(element);
1907  string name = ns.prepend(e.nameStr());
1908  string type = ns.attr<string>(e, _U(type));
1909  string nEntries = ns.attr<string>(e, DD_CMU(nEntries));
1910  string val = e.text();
1911  val.erase(remove_if(val.begin(), val.end(), [](unsigned char x) { return isspace(x); }), val.end());
1912 
1913 #ifdef EDM_ML_DEBUG
1914 
1915  printout(ns.context()->debug_constants ? ALWAYS : DEBUG,
1916  "DD4CMS",
1917  "+++ Vector<%s>: %s[%s]: %s",
1918  type.c_str(),
1919  name.c_str(),
1920  nEntries.c_str(),
1921  val.c_str());
1922 
1923 #endif
1924 
1925  try {
1926  std::vector<double> results = splitNumeric(val);
1927  registry->insert(
1928  {name,
1929  results}); //tbb::concurrent_vector<double, tbb::cache_aligned_allocator<double>>(results.begin(), results.end())});
1930  } catch (const exception& e) {
1931 #ifdef EDM_ML_DEBUG
1932 
1933  printout(INFO,
1934  "DD4CMS",
1935  "++ Unresolved Vector<%s>: %s[%s]: %s. Try to resolve later. [%s]",
1936  type.c_str(),
1937  name.c_str(),
1938  nEntries.c_str(),
1939  val.c_str(),
1940  e.what());
1941 
1942 #endif
1943 
1944  std::vector<string> results = splitString(val);
1945  context->unresolvedVectors.insert({name, results});
1946  }
1947 }
1948 
1949 template <>
1950 void Converter<debug>::operator()(xml_h dbg) const {
1951  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1952  if (dbg.hasChild(DD_CMU(debug_constants)))
1953  ns.setContext()->debug_constants = true;
1954  if (dbg.hasChild(DD_CMU(debug_materials)))
1955  ns.setContext()->debug_materials = true;
1956  if (dbg.hasChild(DD_CMU(debug_rotations)))
1957  ns.setContext()->debug_rotations = true;
1958  if (dbg.hasChild(DD_CMU(debug_shapes)))
1959  ns.setContext()->debug_shapes = true;
1960  if (dbg.hasChild(DD_CMU(debug_volumes)))
1961  ns.setContext()->debug_volumes = true;
1962  if (dbg.hasChild(DD_CMU(debug_placements)))
1963  ns.setContext()->debug_placements = true;
1964  if (dbg.hasChild(DD_CMU(debug_namespaces)))
1965  ns.setContext()->debug_namespaces = true;
1966  if (dbg.hasChild(DD_CMU(debug_includes)))
1967  ns.setContext()->debug_includes = true;
1968  if (dbg.hasChild(DD_CMU(debug_algorithms)))
1969  ns.setContext()->debug_algorithms = true;
1970  if (dbg.hasChild(DD_CMU(debug_specpars)))
1971  ns.setContext()->debug_specpars = true;
1972 }
1973 
1974 template <>
1975 void Converter<DDRegistry>::operator()(xml_h /* element */) const {
1976  cms::DDParsingContext* context = _param<cms::DDParsingContext>();
1977  DDRegistry* res = _option<DDRegistry>();
1978  cms::DDNamespace ns(context);
1979  int count = 0;
1980 
1981 #ifdef EDM_ML_DEBUG
1982 
1983  printout(context->debug_constants ? ALWAYS : DEBUG,
1984  "DD4CMS",
1985  "+++ RESOLVING %ld unknown constants..... (out of %ld)",
1986  res->unresolvedConst.size(),
1987  res->originalConst.size());
1988 #endif
1989 
1990  while (!res->unresolvedConst.empty()) {
1991  for (auto& i : res->unresolvedConst) {
1992  const string& n = i.first;
1993  string rep;
1994  string& v = i.second;
1995  size_t idx, idq;
1996  for (idx = v.find('[', 0); idx != string::npos; idx = v.find('[', idx + 1)) {
1997  idq = v.find(']', idx + 1);
1998  rep = v.substr(idx + 1, idq - idx - 1);
1999  auto r = res->originalConst.find(rep);
2000  if (r != res->originalConst.end()) {
2001  rep = "(" + (*r).second + ")";
2002  v.replace(idx, idq - idx + 1, rep);
2003  }
2004  }
2005  if (v.find(']') == string::npos) {
2006  if (v.find("-+") != string::npos || v.find("+-") != string::npos) {
2007  while ((idx = v.find("-+")) != string::npos)
2008  v.replace(idx, 2, "-");
2009  while ((idx = v.find("+-")) != string::npos)
2010  v.replace(idx, 2, "-");
2011  }
2012 
2013 #ifdef EDM_ML_DEBUG
2014 
2015  printout(context->debug_constants ? ALWAYS : DEBUG,
2016  "DD4CMS",
2017  "+++ [%06ld] ---------- %-40s = %s",
2018  res->unresolvedConst.size() - 1,
2019  n.c_str(),
2020  res->originalConst[n].c_str());
2021 
2022 #endif
2023 
2024  ns.addConstantNS(n, v, "number");
2025  res->unresolvedConst.erase(n);
2026  break;
2027  }
2028  }
2029  if (++count > 10000)
2030  break;
2031  }
2032  if (!res->unresolvedConst.empty()) {
2033  for (const auto& e : res->unresolvedConst)
2034  printout(ERROR, "DD4CMS", "+++ Unresolved constant: %-40s = %s.", e.first.c_str(), e.second.c_str());
2035  except("DD4CMS", "++ FAILED to resolve %ld constant entries:", res->unresolvedConst.size());
2036  }
2037  res->unresolvedConst.clear();
2038  res->originalConst.clear();
2039 }
2040 
2041 template <>
2042 void Converter<print_xml_doc>::operator()(xml_h element) const {
2043  string fname = xml::DocumentHandler::system_path(element);
2044 
2045 #ifdef EDM_ML_DEBUG
2046 
2047  printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS : DEBUG,
2048  "DD4CMS",
2049  "+++ Processing data from: %s",
2050  fname.c_str());
2051 
2052 #endif
2053 }
2054 
2056 static long load_dddefinition(Detector& det, xml_h element) {
2057  xml_elt_t dddef(element);
2058  if (dddef) {
2059  cms::DDParsingContext context(det);
2060  cms::DDNamespace ns(context);
2061  ns.addConstantNS("world_x", "101*m", "number");
2062  ns.addConstantNS("world_y", "101*m", "number");
2063  ns.addConstantNS("world_z", "450*m", "number");
2064  ns.addConstantNS("Air", "materials:Air", "string");
2065  ns.addConstantNS("Vacuum", "materials:Vacuum", "string");
2066 
2067  string fname = xml::DocumentHandler::system_path(element);
2068  bool open_geometry = dddef.hasChild(DD_CMU(open_geometry)) ? dddef.child(DD_CMU(open_geometry)) : true;
2069  bool close_geometry = dddef.hasChild(DD_CMU(close_geometry)) ? dddef.hasChild(DD_CMU(close_geometry)) : true;
2070 
2071  xml_coll_t(dddef, _U(debug)).for_each(Converter<debug>(det, &context));
2072 
2073  // Here we define the order how XML elements are processed.
2074  // Be aware of dependencies. This can only defined once.
2075  // At the end it is a limitation of DOM....
2076  printout(INFO, "DD4CMS", "+++ Processing the CMS detector description %s", fname.c_str());
2077 
2078  xml::Document doc;
2079  Converter<print_xml_doc> print_doc(det, &context);
2080  try {
2081  DDRegistry res;
2082  res.unresolvedConst.reserve(2000);
2083  res.originalConst.reserve(6000);
2084  print_doc((doc = dddef.document()).root());
2085  xml_coll_t(dddef, DD_CMU(ConstantsSection)).for_each(Converter<ConstantsSection>(det, &context, &res));
2086  xml_coll_t(dddef, DD_CMU(RotationSection)).for_each(Converter<RotationSection>(det, &context));
2087  xml_coll_t(dddef, DD_CMU(MaterialSection)).for_each(Converter<MaterialSection>(det, &context));
2088 
2089  xml_coll_t(dddef, DD_CMU(IncludeSection)).for_each(DD_CMU(Include), Converter<include_load>(det, &context, &res));
2090 
2091  for (xml::Document d : res.includes) {
2092  print_doc((doc = d).root());
2093  Converter<include_constants>(det, &context, &res)((doc = d).root());
2094  }
2095  // Before we continue, we have to resolve all constants NOW!
2096  Converter<DDRegistry>(det, &context, &res)(dddef);
2097  {
2098  DDVectorsMap* registry = context.description.extension<DDVectorsMap>();
2099 
2100  printout(context.debug_constants ? ALWAYS : DEBUG,
2101  "DD4CMS",
2102  "+++ RESOLVING %ld Vectors.....",
2103  context.unresolvedVectors.size());
2104 
2105  while (!context.unresolvedVectors.empty()) {
2106  for (auto it = context.unresolvedVectors.begin(); it != context.unresolvedVectors.end();) {
2107  std::vector<double> result;
2108  for (const auto& i : it->second) {
2109  result.emplace_back(dd4hep::_toDouble(i));
2110  }
2111  registry->insert({it->first, result});
2112  // All components are resolved
2113  it = context.unresolvedVectors.erase(it);
2114  }
2115  }
2116  }
2117  // Now we can process the include files one by one.....
2118  for (xml::Document d : res.includes) {
2119  print_doc((doc = d).root());
2120  xml_coll_t(d.root(), DD_CMU(MaterialSection)).for_each(Converter<MaterialSection>(det, &context));
2121  }
2122  {
2123  printout(context.debug_materials ? ALWAYS : DEBUG,
2124  "DD4CMS",
2125  "+++ RESOLVING %ld unknown material constituents.....",
2126  context.unresolvedMaterials.size());
2127 
2128  // Resolve referenced materials (if any)
2129 
2130  while (!context.unresolvedMaterials.empty()) {
2131  for (auto it = context.unresolvedMaterials.begin(); it != context.unresolvedMaterials.end();) {
2132  auto const& name = it->first;
2133  std::vector<bool> valid;
2134 
2135  printout(context.debug_materials ? ALWAYS : DEBUG,
2136  "DD4CMS",
2137  "+++ [%06ld] ---------- %s",
2138  context.unresolvedMaterials.size(),
2139  name.c_str());
2140 
2141  auto mat = ns.material(name);
2142  for (auto& mit : it->second) {
2143  printout(context.debug_materials ? ALWAYS : DEBUG,
2144  "DD4CMS",
2145  "+++ component %-48s Fraction: %.6f",
2146  mit.name.c_str(),
2147  mit.fraction);
2148  auto fmat = ns.material(mit.name);
2149  if (nullptr != fmat.ptr()) {
2150  if (mat.ptr()->GetMaterial()->IsMixture()) {
2151  valid.emplace_back(true);
2152  static_cast<TGeoMixture*>(mat.ptr()->GetMaterial())
2153  ->AddElement(fmat.ptr()->GetMaterial(), mit.fraction);
2154  }
2155  }
2156  }
2157  // All components are resolved
2158  if (valid.size() == it->second.size())
2159  it = context.unresolvedMaterials.erase(it);
2160  else
2161  ++it;
2162  }
2163  // Do it again if there are unresolved
2164  // materials left after this pass
2165  }
2166  }
2167  if (open_geometry) {
2168  det.init();
2169  ns.addVolume(det.worldVolume());
2170  }
2171  for (xml::Document d : res.includes) {
2172  print_doc((doc = d).root());
2173  xml_coll_t(d.root(), DD_CMU(RotationSection)).for_each(Converter<RotationSection>(det, &context));
2174  }
2175  for (xml::Document d : res.includes) {
2176  print_doc((doc = d).root());
2177  xml_coll_t(d.root(), DD_CMU(SolidSection)).for_each(Converter<SolidSection>(det, &context));
2178  }
2179  for (xml::Document d : res.includes) {
2180  print_doc((doc = d).root());
2181  xml_coll_t(d.root(), DD_CMU(LogicalPartSection)).for_each(Converter<LogicalPartSection>(det, &context));
2182  }
2183  for (xml::Document d : res.includes) {
2184  print_doc((doc = d).root());
2185  xml_coll_t(d.root(), DD_CMU(Algorithm)).for_each(Converter<DDLAlgorithm>(det, &context));
2186  }
2187  for (xml::Document d : res.includes) {
2188  print_doc((doc = d).root());
2189  xml_coll_t(d.root(), DD_CMU(PosPartSection)).for_each(Converter<PosPartSection>(det, &context));
2190  }
2191  for (xml::Document d : res.includes) {
2192  print_doc((doc = d).root());
2193  xml_coll_t(d.root(), DD_CMU(SpecParSection)).for_each(Converter<SpecParSection>(det, &context));
2194  }
2195 
2197  for (xml::Document d : res.includes)
2198  Converter<include_unload>(det, &context, &res)(d.root());
2199 
2200  print_doc((doc = dddef.document()).root());
2201  // Now process the actual geometry items
2202  xml_coll_t(dddef, DD_CMU(SolidSection)).for_each(Converter<SolidSection>(det, &context));
2203  {
2204  // Before we continue, we have to resolve all shapes NOW!
2205  // Note: This only happens in a legacy DB payloads where
2206  // boolean shapes can be defined before thier
2207  // component shapes
2208 
2209  while (!context.unresolvedShapes.empty()) {
2210  for (auto it = context.unresolvedShapes.begin(); it != context.unresolvedShapes.end();) {
2211  auto const& name = it->first;
2212  auto const& aname = std::visit([](auto&& arg) -> std::string { return arg.firstSolidName; }, it->second);
2213  auto const& bname = std::visit([](auto&& arg) -> std::string { return arg.secondSolidName; }, it->second);
2214 
2215  auto const& ait = context.shapes.find(aname);
2216  if (ait->second.isValid()) {
2217  auto const& bit = context.shapes.find(bname);
2218  if (bit->second.isValid()) {
2219  dd4hep::Solid shape =
2220  std::visit([&ait, &bit](auto&& arg) -> dd4hep::Solid { return arg.make(ait->second, bit->second); },
2221  it->second);
2222  context.shapes[name] = shape;
2223  it = context.unresolvedShapes.erase(it);
2224  } else
2225  ++it;
2226  } else
2227  ++it;
2228  }
2229  }
2230  }
2231  xml_coll_t(dddef, DD_CMU(LogicalPartSection)).for_each(Converter<LogicalPartSection>(det, &context));
2232  xml_coll_t(dddef, DD_CMU(Algorithm)).for_each(Converter<DDLAlgorithm>(det, &context));
2233  xml_coll_t(dddef, DD_CMU(PosPartSection)).for_each(Converter<PosPartSection>(det, &context));
2234  xml_coll_t(dddef, DD_CMU(SpecParSection)).for_each(Converter<SpecParSection>(det, &context));
2235  } catch (const exception& e) {
2236  printout(ERROR, "DD4CMS", "Exception while processing xml source:%s", doc.uri().c_str());
2237  printout(ERROR, "DD4CMS", "----> %s", e.what());
2238  throw;
2239  }
2240 
2242  if (close_geometry) {
2243  Volume wv = det.worldVolume();
2244  Volume geomv = ns.volume("cms:OCMS", false);
2245  if (geomv.isValid())
2246  wv.placeVolume(geomv, 1);
2247  Volume mfv = ns.volume("cmsMagneticField:MAGF", false);
2248  if (mfv.isValid())
2249  wv.placeVolume(mfv, 1);
2250  Volume mfv1 = ns.volume("MagneticFieldVolumes:MAGF", false);
2251  if (mfv1.isValid())
2252  wv.placeVolume(mfv1, 1);
2253 
2254  // Can not deal with reflections without closed geometry
2255  det.manager().CloseGeometry();
2256 
2257  det.endDocument();
2258  }
2259  printout(INFO, "DDDefinition", "+++ Finished processing %s", fname.c_str());
2260  return 1;
2261  }
2262  except("DDDefinition", "+++ FAILED to process unknown DOM tree [Invalid Handle]");
2263  return 0;
2264 }
2265 
2266 // Now declare the factory entry for the plugin mechanism
2267 DECLARE_XML_DOC_READER(DDDefinition, load_dddefinition)
DDLVector
DDLVector handles Rotation and ReflectionRotation elements.
Definition: DDLVector.h:29
runTheMatrix.ret
ret
prodAgent to be discontinued
Definition: runTheMatrix.py:542
originalConst
std::unordered_map< std::string, std::string > originalConst
Definition: DDDefinitions2Objects.cc:56
DDAxes::y
photonAnalyzer_cfi.rMax
rMax
Definition: photonAnalyzer_cfi.py:91
ApeEstimator_cff.width
width
Definition: ApeEstimator_cff.py:24
pixelCPEforGPU::Rotation
SOARotation< float > Rotation
Definition: pixelCPEforGPU.h:17
common_cff.doc
doc
Definition: common_cff.py:54
mps_fire.i
i
Definition: mps_fire.py:428
cms_units::operators
Definition: CMSUnits.h:13
geometryCSVtoXML.zz
zz
Definition: geometryCSVtoXML.py:19
cms::DDParsingContext::unresolvedMaterials
std::unordered_map< std::string, std::vector< CompositeMaterial > > unresolvedMaterials
Definition: DDParsingContext.h:76
cms::DDParsingContext::unresolvedVectors
std::unordered_map< std::string, std::vector< std::string > > unresolvedVectors
Definition: DDParsingContext.h:77
geometryCSVtoXML.yz
yz
Definition: geometryCSVtoXML.py:19
g4SimHits_cfi.Material
Material
Definition: g4SimHits_cfi.py:582
dqmiodumpmetadata.n
n
Definition: dqmiodumpmetadata.py:28
funct::Constant
Polynomial< 0 > Constant
Definition: Constant.h:6
for_each_token
void for_each_token(InputIt first, InputIt last, ForwardIt s_first, ForwardIt s_last, BinOp binary_op)
Definition: DDDefinitions2Objects.cc:1856
cms::DDNamespace::solid
dd4hep::Solid solid(const std::string &name) const
Definition: DDNamespace.cc:240
HLT_FULL_cff.Class
Class
Definition: HLT_FULL_cff.py:8427
L1EGammaCrystalsEmulatorProducer_cfi.scale
scale
Definition: L1EGammaCrystalsEmulatorProducer_cfi.py:10
cms::hash
constexpr unsigned int hash(const char *str, int h=0)
Definition: DDAlgoArguments.h:18
DDLSpecPar
DDLSpecPar processes SpecPar elements.
Definition: DDLSpecPar.h:26
cms::DDNamespace::material
dd4hep::Material material(const std::string &name) const
Definition: DDNamespace.cc:116
filterCSVwithJSON.copy
copy
Definition: filterCSVwithJSON.py:36
DDLSphere
DDLSphere processes all Sphere elements.
Definition: DDLSphere.h:24
DDParsingContext.h
DiDispStaMuonMonitor_cfi.pt
pt
Definition: DiDispStaMuonMonitor_cfi.py:39
convertSQLitetoXML_cfg.output
output
Definition: convertSQLitetoXML_cfg.py:72
DDLTubs
DDLTubs processes Tubs elements.
Definition: DDLTubs.h:21
cond::hash
Definition: Time.h:19
cms::DDParsingContext
Definition: DDParsingContext.h:13
angle_units::operators::convertRadToDeg
constexpr NumType convertRadToDeg(NumType radians)
Definition: angle_units.h:21
cms::DDNamespace
Definition: DDNamespace.h:16
edmLumisInFiles.description
description
Definition: edmLumisInFiles.py:11
pos
Definition: PixelAliasList.h:18
HLT_FULL_cff.Algorithm
Algorithm
Definition: HLT_FULL_cff.py:9477
cms::DDParsingContext::debug_placements
bool debug_placements
Definition: DDParsingContext.h:63
interestingEgammaIsoDetIdsSequence_cff.outerRadius
outerRadius
Definition: interestingEgammaIsoDetIdsSequence_cff.py:14
Types.optional
optional
Definition: Types.py:199
cms::makeRotation3D
DDRotationMatrix makeRotation3D(double thetaX, double phiX, double thetaY, double phiY, double thetaZ, double phiZ)
Definition: DDAlgoArguments.cc:20
edm::second
U second(std::pair< T, U > const &p)
Definition: ParameterSet.cc:222
bookConverter.results
results
Definition: bookConverter.py:144
splitString
std::vector< std::string > splitString(const std::string &fLine)
Definition: HcalDbASCIIIO.cc:58
DDLPseudoTrap
Definition: DDLPseudoTrap.h:23
personalPlayback.fp
fp
Definition: personalPlayback.py:523
cms::DDNamespace::addConstantNS
void addConstantNS(const std::string &name, const std::string &value, const std::string &type) const
Definition: DDNamespace.cc:101
DDLLogicalPart
DDLLogicalPart processes LogicalPart elements.
Definition: DDLLogicalPart.h:34
cms::DDParsingContext::CompositeMaterial
Definition: DDParsingContext.h:49
DDAxes::x
gpuVertexFinder::wv
float *__restrict__ wv
Definition: gpuFitVertices.h:27
cms::PlacedVolume
dd4hep::PlacedVolume PlacedVolume
Definition: DDFilteredView.h:48
findQualityFiles.v
v
Definition: findQualityFiles.py:179
DDLElementaryMaterial
DDLElementaryMaterial processes ElementaryMaterial elements.
Definition: DDLElementaryMaterial.h:28
DDDetector.h
DDLCompositeMaterial
DDLCompositeMaterial processes all CompositeMaterial elements.
Definition: DDLCompositeMaterial.h:31
geometryDiff.epsilon
int epsilon
Definition: geometryDiff.py:26
FileInPath.h
heavyIonCSV_trainingSettings.idx
idx
Definition: heavyIonCSV_trainingSettings.py:5
Vector
ROOT::Math::Plane3D::Vector Vector
Definition: EcalHitMaker.cc:29
DDLCone
DDLCone processes all Cone elements.
Definition: DDLCone.h:27
GetRecoTauVFromDQM_MC_cff.cl
cl
Definition: GetRecoTauVFromDQM_MC_cff.py:38
edm::FileInPath
Definition: FileInPath.h:64
unresolvedConst
std::unordered_map< std::string, std::string > unresolvedConst
Definition: DDDefinitions2Objects.cc:55
dqmdumpme.last
last
Definition: dqmdumpme.py:56
debug
#define debug
Definition: HDRShower.cc:19
convert_boolean
static void convert_boolean(cms::DDParsingContext *context, xml_h element)
Definition: DDDefinitions2Objects.cc:1048
DDAxes::undefined
cms::DDParsingContext::debug_materials
bool debug_materials
Definition: DDParsingContext.h:59
DDLEllipticalTube
DDLEllipticalTube processes all EllipticalTube elements.
Definition: DDLEllipticalTube.h:24
SiPixelRawToDigiRegional_cfi.deltaPhi
deltaPhi
Definition: SiPixelRawToDigiRegional_cfi.py:9
HLT_FULL_cff.fraction
fraction
Definition: HLT_FULL_cff.py:52802
DDLBox
DDLBox processes Box elements.
Definition: DDLBox.h:27
DDAxes::z
str
#define str(s)
Definition: TestProcessor.cc:52
DDLRotationByAxis
DDLRotationByAxis handles RotationByAxis elements.
Definition: DDLRotationByAxis.h:25
submitPVResolutionJobs.count
count
Definition: submitPVResolutionJobs.py:352
theta
Geom::Theta< T > theta() const
Definition: Basic3DVectorLD.h:150
HcalDetIdTransform::transform
unsigned transform(const HcalDetId &id, unsigned transformCode)
Definition: HcalDetIdTransform.cc:7
PixelTestBeamValidation_cfi.Position
Position
Definition: PixelTestBeamValidation_cfi.py:75
DDLTorus
Definition: DDLTorus.h:23
DDLAlgorithm
DDLAlgorithm processes Algorithm elements.
Definition: DDLAlgorithm.h:25
sistrip::SpyUtilities::isValid
const bool isValid(const Frame &aFrame, const FrameQuality &aQuality, const uint16_t aExpectedPos)
Definition: SiStripSpyUtilities.cc:124
first
auto first
Definition: CAHitNtupletGeneratorKernelsImpl.h:112
DDLPosPart
DDLPosPart handles PosPart elements.
Definition: DDLPosPart.h:27
geometryCSVtoXML.xy
xy
Definition: geometryCSVtoXML.py:19
DDAlgoArguments.h
DDAxes::rho
AlCaHLTBitMon_QueryRunRegistry.string
string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
cms::DDParsingContext::shapes
std::unordered_map< std::string, dd4hep::Solid > shapes
Definition: DDParsingContext.h:72
unpackBuffers-CaloStage2.INFO
INFO
Definition: unpackBuffers-CaloStage2.py:169
cppFunctionSkipper.exception
exception
Definition: cppFunctionSkipper.py:10
cms::Volume
dd4hep::Volume Volume
Definition: DDFilteredView.h:47
idealTransformation.rotation
dictionary rotation
Definition: idealTransformation.py:1
geometryCSVtoXML.yy
yy
Definition: geometryCSVtoXML.py:19
cms::DDParsingContext::BooleanShape
Definition: DDParsingContext.h:36
DDAxes
DDAxes
analagous to geant4/source/global/HEPGeometry/include/geomdefs.hh
Definition: DDAxes.h:11
type
type
Definition: SiPixelVCal_PayloadInspector.cc:37
geometryCSVtoXML.xz
xz
Definition: geometryCSVtoXML.py:19
thread_safety_macros.h
interestingEgammaIsoDetIdsSequence_cff.innerRadius
innerRadius
Definition: interestingEgammaIsoDetIdsSequence_cff.py:15
includes
std::vector< xml::Document > includes
Definition: DDDefinitions2Objects.cc:54
createfilelist.int
int
Definition: createfilelist.py:10
MetAnalyzer.pv
def pv(vc)
Definition: MetAnalyzer.py:7
load_dddefinition
static long load_dddefinition(Detector &det, xml_h element)
Converter for <DDDefinition> tags.
Definition: DDDefinitions2Objects.cc:2056
value
Definition: value.py:1
cuy.rep
rep
Definition: cuy.py:1190
cms::DDNamespace::addVolume
dd4hep::Volume addVolume(dd4hep::Volume vol) const
Add rotation matrix to current namespace.
Definition: DDNamespace.cc:165
root
Definition: RooFitFunction.h:10
M_PI
#define M_PI
Definition: BXVectorInputProducer.cc:49
DDLRotationSequence
DDLRotationSequence handles a set of Rotations.
Definition: DDLRotationSequence.h:24
Translation
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > Translation
Definition: PGeometricDetBuilder.cc:20
cms::DDNamespace::addSolid
dd4hep::Solid addSolid(const std::string &name, dd4hep::Solid solid) const
Definition: DDNamespace.cc:236
PVValHelper::dy
Definition: PVValidationHelpers.h:50
DOFs::thetaY
Definition: AlignPCLThresholdsWriter.cc:37
DDLTrapezoid
Definition: DDLTrapezoid.h:23
res
Definition: Electron.h:6
fileinputsource_cfi.sec
sec
Definition: fileinputsource_cfi.py:87
cms::s_executed
static constexpr long s_executed
Definition: DDAlgoArguments.h:16
alignCSCRings.r
r
Definition: alignCSCRings.py:93
DDAxes::phi
alignmentValidation.fname
string fname
main script
Definition: alignmentValidation.py:959
DOFs::thetaX
Definition: AlignPCLThresholdsWriter.cc:37
align::Detector
Definition: StructureType.h:92
bookConverter.elements
elements
Definition: bookConverter.py:147
heppy_batch.val
val
Definition: heppy_batch.py:351
eostools.move
def move(src, dest)
Definition: eostools.py:511
std
Definition: JetResolutionObject.h:76
submitPVValidationJobs.child
child
Definition: submitPVValidationJobs.py:119
cms::DDParsingContext::debug_constants
bool debug_constants
Definition: DDParsingContext.h:58
DDLDivision
DDLDivision processes Division elements.
Definition: DDLDivision.h:27
PVValHelper::dz
Definition: PVValidationHelpers.h:51
cms::DDParsingContext::debug_rotations
bool debug_rotations
Definition: DDParsingContext.h:60
cms::DDNamespace::context
DDParsingContext *const context() const
Definition: DDNamespace.h:69
DOFs::thetaZ
Definition: AlignPCLThresholdsWriter.cc:37
HGCalGeometryMode::Polyhedra
Definition: HGCalGeometryMode.h:37
relativeConstraints.value
value
Definition: relativeConstraints.py:53
dd4hep
Definition: DDPlugins.h:8
runonSM.TYPE
TYPE
Definition: runonSM.py:21
cms::DDVectorsMap
std::unordered_map< std::string, std::vector< double > > DDVectorsMap
Definition: DDNamespace.h:14
genVertex_cff.x
x
Definition: genVertex_cff.py:12
DD_CMU
#define DD_CMU(a)
Definition: DDXMLTags.h:183
makeMuonMisalignmentScenario.rot
rot
Definition: makeMuonMisalignmentScenario.py:322
CosmicsPD_Skims.radius
radius
Definition: CosmicsPD_Skims.py:135
HGCalGeometryMode::ExtrudedPolygon
Definition: HGCalGeometryMode.h:37
angle
T angle(T x1, T y1, T z1, T x2, T y2, T z2)
Definition: angle.h:11
Skims_PA_cff.name
name
Definition: Skims_PA_cff.py:17
DEBUG
#define DEBUG
Definition: DMRChecker.cc:119
CMSUnits.h
DDNamespace.h
NAMESPACE_SEP
#define NAMESPACE_SEP
Definition: DDNamespace.h:85
photonAnalyzer_cfi.rMin
rMin
Definition: photonAnalyzer_cfi.py:90
funct::arg
A arg
Definition: Factorize.h:31
ztail.d
d
Definition: ztail.py:151
mps_fire.result
result
Definition: mps_fire.py:311
castor_dqm_sourceclient_file_cfg.path
path
Definition: castor_dqm_sourceclient_file_cfg.py:37
funct::abs
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
RunInfoPI::valid
Definition: RunInfoPayloadInspectoHelper.h:16
c
auto & c
Definition: CAHitNtupletGeneratorKernelsImpl.h:46
hltrates_dqm_sourceclient-live_cfg.offset
offset
Definition: hltrates_dqm_sourceclient-live_cfg.py:82
child
Definition: simpleInheritance.h:11
dqm::qstatus::ERROR
static const int ERROR
Definition: MonitorElement.h:54
submitPVValidationJobs.t
string t
Definition: submitPVValidationJobs.py:644
GeneratorMix_cff.mix
mix
Definition: GeneratorMix_cff.py:6
dd4hep::createPlacement
TGeoCombiTrans * createPlacement(const Rotation3D &iRot, const Position &iTrans)
Definition: DDDefinitions2Objects.cc:109
cms::DDParsingContext::unresolvedShapes
std::unordered_map< std::string, std::variant< BooleanShape< dd4hep::UnionSolid >, BooleanShape< dd4hep::SubtractionSolid >, BooleanShape< dd4hep::IntersectionSolid > > > unresolvedShapes
Definition: DDParsingContext.h:82
class-composition.parent
parent
Definition: class-composition.py:88
cms::DDNamespace::volume
dd4hep::Volume volume(const std::string &name, bool exc=true) const
Definition: DDNamespace.cc:205
PVValHelper::dx
Definition: PVValidationHelpers.h:49
cms::DDParsingContext::description
dd4hep::Detector & description
Definition: DDParsingContext.h:68
geometryCSVtoXML.xx
xx
Definition: geometryCSVtoXML.py:19
g
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
fastSimProducer_cff.density
density
Definition: fastSimProducer_cff.py:61
GetRecoTauVFromDQM_MC_cff.next
next
Definition: GetRecoTauVFromDQM_MC_cff.py:31
cms
Namespace of DDCMS conversion namespace.
Definition: ProducerAnalyzer.cc:21
MillePedeFileConverter_cfg.e
e
Definition: MillePedeFileConverter_cfg.py:37
cms::makeRotReflect
DDRotationMatrix makeRotReflect(double thetaX, double phiX, double thetaY, double phiY, double thetaZ, double phiZ)
Definition: DDAlgoArguments.cc:32