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