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  double density = xmat.attr<double>(DD_CMU(density)) / (dd4hep::g / dd4hep::cm3);
594  xml_coll_t composites(xmat, DD_CMU(MaterialFraction));
595  TGeoMixture* mix = new TGeoMixture(nam.c_str(), composites.size(), density);
596 
597 #ifdef EDM_ML_DEBUG
598 
599  printout(ns.context()->debug_materials ? ALWAYS : DEBUG,
600  "DD4CMS",
601  "++ Converting material %-48s Density: %8.3f [g/cm3] ROOT: %8.3f [g/cm3]",
602  ('"' + nam + '"').c_str(),
603  density,
604  mix->GetDensity());
605 
606 #endif
607 
608  if (ns.context()->makePayload) {
609  ns.context()->compMaterialsVec.emplace_back(std::make_pair(nam, density));
610  }
611  for (composites.reset(); composites; ++composites) {
612  xml_dim_t xfrac(composites);
613  xml_dim_t xfrac_mat(xfrac.child(DD_CMU(rMaterial)));
614  double fraction = xfrac.fraction();
615  string fracname = ns.realName(xfrac_mat.nameStr());
616 
617  if (ns.context()->makePayload) {
618  ns.context()->compMaterialsRefs[nam].emplace_back(
619  cms::DDParsingContext::CompositeMaterial(ns.prepend(fracname), fraction));
620  }
621  TGeoMaterial* frac_mat = mgr.GetMaterial(fracname.c_str());
622  if (frac_mat == nullptr) // Try to find it within this namespace
623  frac_mat = mgr.GetMaterial(ns.prepend(fracname).c_str());
624  if (frac_mat) {
625  mix->AddElement(frac_mat, fraction);
626  continue;
627  }
628 
629  throw cms::Exception("DD4CMS") << "Composite material \"" + fracname + "\" or \"" + ns.prepend(fracname) +
630  "\" not yet defined.";
631  }
632  mix->SetTemperature(ns.context()->description.stdConditions().temperature);
633  mix->SetPressure(ns.context()->description.stdConditions().pressure);
634  mix->SetRadLen(0e0);
636  TGeoMedium* medium = mgr.GetMedium(nam.c_str());
637  if (nullptr == medium) {
638  --unique_mat_id;
639  medium = new TGeoMedium(nam.c_str(), unique_mat_id, mix);
640  medium->SetTitle("material");
641  medium->SetUniqueID(unique_mat_id);
642  }
643  }
644 }
645 
647 template <>
648 void Converter<DDLRotation>::operator()(xml_h element) const {
649  cms::DDParsingContext* context = _param<cms::DDParsingContext>();
651  xml_dim_t xrot(element);
652  string nam = xrot.nameStr();
653  double thetaX = xrot.hasAttr(DD_CMU(thetaX)) ? ns.attr<double>(xrot, DD_CMU(thetaX)) : 0e0;
654  double phiX = xrot.hasAttr(DD_CMU(phiX)) ? ns.attr<double>(xrot, DD_CMU(phiX)) : 0e0;
655  double thetaY = xrot.hasAttr(DD_CMU(thetaY)) ? ns.attr<double>(xrot, DD_CMU(thetaY)) : 0e0;
656  double phiY = xrot.hasAttr(DD_CMU(phiY)) ? ns.attr<double>(xrot, DD_CMU(phiY)) : 0e0;
657  double thetaZ = xrot.hasAttr(DD_CMU(thetaZ)) ? ns.attr<double>(xrot, DD_CMU(thetaZ)) : 0e0;
658  double phiZ = xrot.hasAttr(DD_CMU(phiZ)) ? ns.attr<double>(xrot, DD_CMU(phiZ)) : 0e0;
659  Rotation3D rot = makeRotation3D(thetaX, phiX, thetaY, phiY, thetaZ, phiZ);
660 
661 #ifdef EDM_ML_DEBUG
662 
663  printout(context->debug_rotations ? ALWAYS : DEBUG,
664  "DD4CMS",
665  "+++ Adding rotation: %-32s: (theta/phi)[rad] X: %6.3f %6.3f Y: %6.3f %6.3f Z: %6.3f %6.3f",
666  ns.prepend(nam).c_str(),
667  thetaX,
668  phiX,
669  thetaY,
670  phiY,
671  thetaZ,
672  phiZ);
673 
674 #endif
675 
676  ns.addRotation(nam, rot);
677 }
678 
680 template <>
681 void Converter<DDLReflectionRotation>::operator()(xml_h element) const {
682  cms::DDParsingContext* context = _param<cms::DDParsingContext>();
684  xml_dim_t xrot(element);
685  string name = xrot.nameStr();
686  double thetaX = xrot.hasAttr(DD_CMU(thetaX)) ? ns.attr<double>(xrot, DD_CMU(thetaX)) : 0e0;
687  double phiX = xrot.hasAttr(DD_CMU(phiX)) ? ns.attr<double>(xrot, DD_CMU(phiX)) : 0e0;
688  double thetaY = xrot.hasAttr(DD_CMU(thetaY)) ? ns.attr<double>(xrot, DD_CMU(thetaY)) : 0e0;
689  double phiY = xrot.hasAttr(DD_CMU(phiY)) ? ns.attr<double>(xrot, DD_CMU(phiY)) : 0e0;
690  double thetaZ = xrot.hasAttr(DD_CMU(thetaZ)) ? ns.attr<double>(xrot, DD_CMU(thetaZ)) : 0e0;
691  double phiZ = xrot.hasAttr(DD_CMU(phiZ)) ? ns.attr<double>(xrot, DD_CMU(phiZ)) : 0e0;
692 
693 #ifdef EDM_ML_DEBUG
694 
695  printout(context->debug_rotations ? ALWAYS : DEBUG,
696  "DD4CMS",
697  "+++ Adding reflection rotation: %-32s: (theta/phi)[rad] X: %6.3f %6.3f Y: %6.3f %6.3f Z: %6.3f %6.3f",
698  ns.prepend(name).c_str(),
699  thetaX,
700  phiX,
701  thetaY,
702  phiY,
703  thetaZ,
704  phiZ);
705 
706 #endif
707 
708  Rotation3D rot = makeRotReflect(thetaX, phiX, thetaY, phiY, thetaZ, phiZ);
709  ns.addRotation(name, rot);
710 }
711 
713 template <>
714 void Converter<DDLRotationSequence>::operator()(xml_h element) const {
715  cms::DDParsingContext* context = _param<cms::DDParsingContext>();
717  xml_dim_t xrot(element);
718  string nam = xrot.nameStr();
719  Rotation3D rot;
720  xml_coll_t rotations(xrot, DD_CMU(RotationByAxis));
721  for (rotations.reset(); rotations; ++rotations) {
722  string axis = ns.attr<string>(rotations, DD_CMU(axis));
723  double angle = ns.attr<double>(rotations, _U(angle));
724  rot = makeRotation3D(rot, axis, angle);
725 
726 #ifdef EDM_ML_DEBUG
727 
728  printout(context->debug_rotations ? ALWAYS : DEBUG,
729  "DD4CMS",
730  "+ Adding rotation to: %-29s: (axis/angle)[rad] Axis: %s Angle: %6.3f",
731  nam.c_str(),
732  axis.c_str(),
733  angle);
734 
735 #endif
736  }
737  double xx, xy, xz;
738  double yx, yy, yz;
739  double zx, zy, zz;
740  rot.GetComponents(xx, xy, xz, yx, yy, yz, zx, zy, zz);
741 
742 #ifdef EDM_ML_DEBUG
743 
744  printout(context->debug_rotations ? ALWAYS : DEBUG,
745  "DD4CMS",
746  "+++ Adding rotation sequence: %-23s: %6.3f %6.3f %6.3f, %6.3f %6.3f %6.3f, %6.3f %6.3f %6.3f",
747  ns.prepend(nam).c_str(),
748  xx,
749  xy,
750  xz,
751  yx,
752  yy,
753  yz,
754  zx,
755  zy,
756  zz);
757 
758 #endif
759 
760  ns.addRotation(nam, rot);
761 }
762 
764 template <>
765 void Converter<DDLRotationByAxis>::operator()(xml_h element) const {
766  cms::DDParsingContext* context = _param<cms::DDParsingContext>();
768  xml_dim_t xrot(element);
769  xml_dim_t par(xrot.parent());
770  if (xrot.hasAttr(_U(name))) {
771  string nam = xrot.nameStr();
772  string axis = ns.attr<string>(xrot, DD_CMU(axis));
773  double angle = ns.attr<double>(xrot, _U(angle));
774  Rotation3D rot;
775  rot = makeRotation3D(rot, axis, angle);
776 
777 #ifdef EDM_ML_DEBUG
778 
779  printout(context->debug_rotations ? ALWAYS : DEBUG,
780  "DD4CMS",
781  "+++ Adding rotation: %-32s: (axis/angle)[rad] Axis: %s Angle: %6.3f",
782  ns.prepend(nam).c_str(),
783  axis.c_str(),
784  angle);
785 
786 #endif
787 
788  ns.addRotation(nam, rot);
789  }
790 }
791 
793 template <>
794 void Converter<DDLLogicalPart>::operator()(xml_h element) const {
795  cms::DDNamespace ns(_param<cms::DDParsingContext>());
796  xml_dim_t e(element);
797  string sol = e.child(DD_CMU(rSolid)).attr<string>(_U(name));
798  string mat = e.child(DD_CMU(rMaterial)).attr<string>(_U(name));
799  string volName = ns.prepend(e.attr<string>(_U(name)));
800  Solid solid = ns.solid(sol);
801  Material material = ns.material(mat);
802  if (ns.context()->assemblySolids.count(sol) == 1) {
803  // To match the general paradigm, an assembly starts as a solid,
804  // and then a logical part is made of the solid. However, the
805  // solid is just a dummy whose names tags it as an assembly.
806  ns.addAssembly(volName, false);
807  return;
808  }
809 
810 #ifdef EDM_ML_DEBUG
811  Volume volume =
812 #endif
813 
814  ns.addVolume(Volume(volName, solid, material));
815 
816 #ifdef EDM_ML_DEBUG
817 
818  printout(ns.context()->debug_volumes ? ALWAYS : DEBUG,
819  "DD4CMS",
820  "+++ %s Volume: %-24s [%s] Shape: %-32s [%s] Material: %-40s [%s]",
821  e.tag().c_str(),
822  volName.c_str(),
823  volume.isValid() ? "VALID" : "INVALID",
824  sol.c_str(),
825  solid.isValid() ? "VALID" : "INVALID",
826  mat.c_str(),
827  material.isValid() ? "VALID" : "INVALID");
828 
829 #endif
830 }
831 
833 template <>
834 void Converter<DDLTransform3D>::operator()(xml_h element) const {
835  cms::DDNamespace ns(_param<cms::DDParsingContext>());
836  Transform3D* tr = _option<Transform3D>();
837  xml_dim_t e(element);
838  xml_dim_t translation = e.child(DD_CMU(Translation), false);
839  xml_dim_t rotation = e.child(DD_CMU(Rotation), false);
840  xml_dim_t refRotation = e.child(DD_CMU(rRotation), false);
841  xml_dim_t refReflectionRotation = e.child(DD_CMU(rReflectionRotation), false);
842  Position pos;
843  Rotation3D rot;
844 
845  if (translation.ptr()) {
846  double x = ns.attr<double>(translation, _U(x));
847  double y = ns.attr<double>(translation, _U(y));
848  double z = ns.attr<double>(translation, _U(z));
849  pos = Position(x, y, z);
850  }
851  if (rotation.ptr()) {
852  double x = ns.attr<double>(rotation, _U(x));
853  double y = ns.attr<double>(rotation, _U(y));
854  double z = ns.attr<double>(rotation, _U(z));
855  rot = RotationZYX(z, y, x);
856  } else if (refRotation.ptr()) {
857  string rotName = ns.prepend(refRotation.nameStr());
858  rot = ns.rotation(rotName);
859  } else if (refReflectionRotation.ptr()) {
860  string rotName = ns.prepend(refReflectionRotation.nameStr());
861  rot = ns.rotation(rotName);
862  }
863  *tr = Transform3D(rot, pos);
864 }
865 
866 static void placeAssembly(Volume* parentPtr,
867  const string& parentName,
868  Volume* childPtr,
869  const string& childName,
870  int copy,
871  const Transform3D& transform,
872  cms::DDNamespace& ns) {
873 #ifdef EDM_ML_DEBUG
874 
875  printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
876  "DD4CMS",
877  "+++ Parent vol: %-24s Child: %-32s, copy:%d",
878  parentName.c_str(),
879  childName.c_str(),
880  copy);
881 
882 #endif
883 
884  TGeoShape* shape = (*childPtr)->GetShape();
885  // Need to fix the daughter's BBox of assemblies, if the BBox was not calculated....
886  if (shape->IsA() == TGeoShapeAssembly::Class()) {
887  TGeoShapeAssembly* as = (TGeoShapeAssembly*)shape;
888  if (std::fabs(as->GetDX()) < numeric_limits<double>::epsilon() &&
889  std::fabs(as->GetDY()) < numeric_limits<double>::epsilon() &&
890  std::fabs(as->GetDZ()) < numeric_limits<double>::epsilon()) {
891  as->NeedsBBoxRecompute();
892  as->ComputeBBox();
893  }
894  }
895  if (ns.context()->validate) {
896  TGeoNode* n;
897  TString nam_id = TString::Format("%s_%d", (*childPtr)->GetName(), copy);
898  n = static_cast<TGeoNode*>((*parentPtr)->GetNode(nam_id));
899  if (n != nullptr) {
900  printout(ERROR, "PlacedVolume", "++ Attempt to add already existing node %s", (const char*)nam_id);
901  return;
902  }
903  }
904 
906  if ((*childPtr)->IsAssembly()) {
907  pv = parentPtr->placeVolume(ns.assembly(childName), copy, transform);
908  } else {
909  pv = parentPtr->placeVolume(*childPtr, copy, transform);
910  }
911 
912  if (!pv.isValid()) {
913  printout(ERROR, "DD4CMS", "+++ Placement FAILED! Parent:%s Child:%s", parentName.c_str(), childName.c_str());
914  }
915 }
916 
918 template <>
919 void Converter<DDLPosPart>::operator()(xml_h element) const {
920  cms::DDNamespace ns(_param<cms::DDParsingContext>()); //, element, true );
921  xml_dim_t e(element);
922  int copy = e.attr<int>(DD_CMU(copyNumber));
923  string parentName = ns.prepend(ns.attr<string>(e.child(DD_CMU(rParent)), _U(name)));
924  string childName = ns.prepend(ns.attr<string>(e.child(DD_CMU(rChild)), _U(name)));
925  Transform3D transform;
926  Converter<DDLTransform3D>(description, param, &transform)(element);
927 
928  Volume parent = ns.volume(parentName, false);
929  Volume child = ns.volume(childName, false);
930  Assembly parAsmb = ns.assembly(parentName, false);
931  Assembly childAsmb = ns.assembly(childName, false);
932 
933 #ifdef EDM_ML_DEBUG
934 
935  printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
936  "DD4CMS",
937  "+++ %s Parent: %-24s [%s] Child: %-32s [%s] copy:%d",
938  e.tag().c_str(),
939  parentName.c_str(),
940  parent.isValid() ? "VALID" : "INVALID",
941  childName.c_str(),
942  child.isValid() ? "VALID" : "INVALID",
943  copy);
944 
945 #endif
946 
947  if (!parent.isValid() && !parAsmb.isValid() && strchr(parentName.c_str(), NAMESPACE_SEP) == nullptr) {
948  parentName = ns.prepend(parentName);
949  parAsmb = ns.assembly(parentName, false);
950  if (!parAsmb.isValid())
951  parent = ns.volume(parentName);
952  }
953 
954  if (!child.isValid() && !childAsmb.isValid() && strchr(childName.c_str(), NAMESPACE_SEP) == nullptr) {
955  childName = ns.prepend(childName);
956  child = ns.volume(childName, false);
957  childAsmb = ns.assembly(childName, false);
958  }
959  if (parAsmb.isValid() || childAsmb.isValid()) {
960  printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
961  "DD4CMS",
962  "***** Placing assembly parent %s, child %s",
963  parentName.c_str(),
964  childName.c_str());
965  Volume* parentPtr = parAsmb.isValid() ? &parAsmb : &parent;
966  Volume* childPtr = childAsmb.isValid() ? &childAsmb : &child;
967  placeAssembly(parentPtr, parentName, childPtr, childName, copy, transform, ns);
968  return;
969  }
970 
971 #ifdef EDM_ML_DEBUG
972 
973  printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
974  "DD4CMS",
975  "+++ %s Parent: %-24s [%s] Child: %-32s [%s] copy:%d",
976  e.tag().c_str(),
977  parentName.c_str(),
978  parent.isValid() ? "VALID" : "INVALID",
979  childName.c_str(),
980  child.isValid() ? "VALID" : "INVALID",
981  copy);
982 
983 #endif
984 
986  if (child.isValid()) {
987  // FIXME: workaround for Reflection rotation
988  // copy from DDCore/src/Volumes.cpp to replace
989  // static PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, int id, TGeoMatrix* transform)
990  if (!parent) {
991  except("dd4hep", "Volume: Attempt to assign daughters to an invalid physical parent volume.");
992  }
993  if (!child) {
994  except("dd4hep", "Volume: Attempt to assign an invalid physical daughter volume.");
995  }
996  TGeoShape* shape = child->GetShape();
997  // Need to fix the daughter's BBox of assemblies, if the BBox was not calculated....
998  if (shape->IsA() == TGeoShapeAssembly::Class()) {
999  TGeoShapeAssembly* as = (TGeoShapeAssembly*)shape;
1000  if (std::fabs(as->GetDX()) < numeric_limits<double>::epsilon() &&
1001  std::fabs(as->GetDY()) < numeric_limits<double>::epsilon() &&
1002  std::fabs(as->GetDZ()) < numeric_limits<double>::epsilon()) {
1003  as->NeedsBBoxRecompute();
1004  as->ComputeBBox();
1005  }
1006  }
1007  TGeoNode* n;
1008  TString nam_id = TString::Format("%s_%d", child->GetName(), copy);
1009  if (ns.context()->validate) {
1010  n = static_cast<TGeoNode*>(parent->GetNode(nam_id));
1011  if (n != nullptr) {
1012  printout(ERROR, "PlacedVolume", "++ Attempt to add already existing node %s", (const char*)nam_id);
1013  }
1014  }
1015 
1016  Rotation3D rot(transform.Rotation());
1017  Translation3D trans(transform.Translation());
1018  double x, y, z;
1019  trans.GetComponents(x, y, z);
1020  Position pos(x, y, z);
1021  parent->AddNode(child, copy, createPlacement(rot, pos));
1022 
1023  n = static_cast<TGeoNode*>(parent->GetNodes()->Last());
1024  assert(n->GetName() == nam_id);
1025  n->TGeoNode::SetUserExtension(new PlacedVolume::Object());
1026  pv = PlacedVolume(n);
1027  }
1028  if (!pv.isValid()) {
1029  printout(ERROR,
1030  "DD4CMS",
1031  "+++ Placement FAILED! Parent:%s Child:%s Valid:%s",
1032  parent.name(),
1033  childName.c_str(),
1034  yes_no(child.isValid()));
1035  }
1036 }
1037 
1039 template <>
1040 void Converter<PartSelector>::operator()(xml_h element) const {
1041  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1042  cms::DDParsingContext* const context = ns.context();
1043  dd4hep::SpecParRegistry& registry = *context->description.extension<dd4hep::SpecParRegistry>();
1044  xml_dim_t e(element);
1045  xml_dim_t specPar = e.parent();
1046  string specParName = specPar.attr<string>(_U(name));
1047  string path = e.attr<string>(DD_CMU(path));
1048 
1049 #ifdef EDM_ML_DEBUG
1050 
1051  printout(ns.context()->debug_specpars ? ALWAYS : DEBUG,
1052  "DD4CMS",
1053  "+++ PartSelector for %s path: %s",
1054  specParName.c_str(),
1055  path.c_str());
1056 
1057 #endif
1058 
1059  size_t pos = std::string::npos;
1060  if ((pos = path.find("//.*:")) != std::string::npos) {
1061  path.erase(pos + 2, 3);
1062  }
1063  registry.specpars[specParName].paths.emplace_back(std::move(path));
1064 }
1065 
1067 template <>
1068 void Converter<Parameter>::operator()(xml_h element) const {
1069  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1070  cms::DDParsingContext* const context = ns.context();
1071  dd4hep::SpecParRegistry& registry = *context->description.extension<dd4hep::SpecParRegistry>();
1072  xml_dim_t e(element);
1073  xml_dim_t specPar = e.parent();
1074  xml_dim_t specParSect = specPar.parent();
1075  string specParName = specPar.attr<string>(_U(name));
1076  string name = e.nameStr();
1077  string value = e.attr<string>(DD_CMU(value));
1078  bool eval = specParSect.hasAttr(_U(eval)) ? specParSect.attr<bool>(_U(eval)) : false;
1079  eval = specPar.hasAttr(_U(eval)) ? specPar.attr<bool>(_U(eval)) : eval;
1080  eval = e.hasAttr(_U(eval)) ? e.attr<bool>(_U(eval)) : eval;
1081 
1082  string type = eval ? "number" : "string";
1083 
1084 #ifdef EDM_ML_DEBUG
1085 
1086  printout(ns.context()->debug_specpars ? ALWAYS : DEBUG,
1087  "DD4CMS",
1088  "+++ Parameter for %s: %s value %s is a %s",
1089  specParName.c_str(),
1090  name.c_str(),
1091  value.c_str(),
1092  type.c_str());
1093 
1094 #endif
1095 
1096  size_t idx = value.find('[');
1097  if (idx == string::npos && type == "number") {
1098  registry.specpars[specParName].numpars[name].emplace_back(dd4hep::_toDouble(value));
1099  return;
1100  }
1101  if (idx == string::npos || type == "string") {
1102  registry.specpars[specParName].spars[name].emplace_back(std::move(value));
1103  return;
1104  }
1105 
1106  while (idx != string::npos) {
1107  ++idx;
1108  size_t idp = value.find(':', idx);
1109  size_t idq = value.find(']', idx);
1110  if (idp == string::npos || idp > idq)
1111  value.insert(idx, ns.name());
1112  else if (idp != string::npos && idp < idq)
1113  value[idp] = NAMESPACE_SEP;
1114  idx = value.find('[', idx);
1115  }
1116 
1117  string rep;
1118  string& v = value;
1119  size_t idq;
1120  for (idx = v.find('[', 0); idx != string::npos; idx = v.find('[', idx + 1)) {
1121  idq = v.find(']', idx + 1);
1122  rep = v.substr(idx + 1, idq - idx - 1);
1123  auto r = ns.context()->description.constants().find(rep);
1124  if (r != ns.context()->description.constants().end()) {
1125  rep = "(" + r->second->type + ")";
1126  v.replace(idx, idq - idx + 1, rep);
1127  }
1128  }
1129  registry.specpars[specParName].numpars[name].emplace_back(dd4hep::_toDouble(value));
1130 }
1131 
1132 template <typename TYPE>
1133 static void convert_boolean(cms::DDParsingContext* context, xml_h element) {
1135  xml_dim_t e(element);
1136  string nam = e.nameStr();
1137  string solidName[2];
1138  Solid solids[2];
1139  Solid boolean;
1140  int cnt = 0;
1141  if (e.hasChild(DD_CMU(rSolid))) {
1142  for (xml_coll_t c(element, DD_CMU(rSolid)); cnt < 2 && c; ++c, ++cnt) {
1143  solidName[cnt] = c.attr<string>(_U(name));
1144  solids[cnt] = ns.solid(c.attr<string>(_U(name)));
1145  }
1146  } else {
1147  solidName[0] = e.attr<string>(DD_CMU(firstSolid));
1148  if ((solids[0] = ns.solid(e.attr<string>(DD_CMU(firstSolid)))).isValid())
1149  ++cnt;
1150  solidName[1] = e.attr<string>(DD_CMU(secondSolid));
1151  if ((solids[1] = ns.solid(e.attr<string>(DD_CMU(secondSolid)))).isValid())
1152  ++cnt;
1153  }
1154  if (cnt != 2) {
1155  except("DD4CMS", "+++ Failed to create boolean solid %s. Found only %d parts.", nam.c_str(), cnt);
1156  }
1157 
1158 #ifdef EDM_ML_DEBUG
1159 
1160  printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
1161  "DD4CMS",
1162  "+++ BooleanSolid: %s Left: %-32s Right: %-32s",
1163  nam.c_str(),
1164  ((solids[0].ptr() == nullptr) ? solidName[0].c_str() : solids[0]->GetName()),
1165  ((solids[1].ptr() == nullptr) ? solidName[1].c_str() : solids[1]->GetName()));
1166 
1167 #endif
1168 
1169  if (solids[0].isValid() && solids[1].isValid()) {
1170  Transform3D trafo;
1171  Converter<DDLTransform3D>(context->description, context, &trafo)(element);
1172  boolean = TYPE(solids[0], solids[1], trafo);
1173  } else {
1174  // Register it for later processing
1175  Transform3D trafo;
1176  Converter<DDLTransform3D>(context->description, context, &trafo)(element);
1177  ns.context()->unresolvedShapes.emplace(nam,
1178  DDParsingContext::BooleanShape<TYPE>(solidName[0], solidName[1], trafo));
1179  if (solids[0].isValid() == false) {
1180  printout(ERROR, "DD4CMS", "++ Solid not defined yet: %s", solidName[0].c_str());
1181  }
1182  if (solids[1].isValid() == false) {
1183  printout(ERROR, "DD4CMS", "++ Solid not defined yet: %s", solidName[1].c_str());
1184  }
1185  printout(ERROR, "DD4CMS", "++ Re-order XML files to prevent references to undefined solids");
1186  }
1187  if (!boolean.isValid()) {
1188  // Delay processing the shape
1189  ns.context()->shapes.emplace(nam, dd4hep::Solid(nullptr));
1190  } else
1191  ns.addSolid(nam, boolean);
1192 }
1193 
1195 template <>
1196 void Converter<DDLUnionSolid>::operator()(xml_h element) const {
1197  convert_boolean<UnionSolid>(_param<cms::DDParsingContext>(), element);
1198 }
1199 
1201 template <>
1202 void Converter<DDLSubtractionSolid>::operator()(xml_h element) const {
1203  convert_boolean<SubtractionSolid>(_param<cms::DDParsingContext>(), element);
1204 }
1205 
1207 template <>
1208 void Converter<DDLIntersectionSolid>::operator()(xml_h element) const {
1209  convert_boolean<IntersectionSolid>(_param<cms::DDParsingContext>(), element);
1210 }
1211 
1213 template <>
1214 void Converter<DDLPolycone>::operator()(xml_h element) const {
1215  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1216  xml_dim_t e(element);
1217  string nam = e.nameStr();
1218  double startPhi = ns.attr<double>(e, DD_CMU(startPhi));
1219  double deltaPhi = ns.attr<double>(e, DD_CMU(deltaPhi));
1220  vector<double> z, rmin, rmax, r;
1221 
1222  for (xml_coll_t rzpoint(element, DD_CMU(RZPoint)); rzpoint; ++rzpoint) {
1223  z.emplace_back(ns.attr<double>(rzpoint, _U(z)));
1224  r.emplace_back(ns.attr<double>(rzpoint, _U(r)));
1225  }
1226  if (z.empty()) {
1227  for (xml_coll_t zplane(element, DD_CMU(ZSection)); zplane; ++zplane) {
1228  rmin.emplace_back(ns.attr<double>(zplane, DD_CMU(rMin)));
1229  rmax.emplace_back(ns.attr<double>(zplane, DD_CMU(rMax)));
1230  z.emplace_back(ns.attr<double>(zplane, _U(z)));
1231  }
1232 
1233 #ifdef EDM_ML_DEBUG
1234 
1235  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1236  "DD4CMS",
1237  "+ Polycone: startPhi=%10.3f [rad] deltaPhi=%10.3f [rad] %4ld z-planes",
1238  startPhi,
1239  deltaPhi,
1240  z.size());
1241 
1242 #endif
1243 
1244  ns.addSolid(nam, Polycone(startPhi, deltaPhi, rmin, rmax, z));
1245  } else {
1246 #ifdef EDM_ML_DEBUG
1247 
1248  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1249  "DD4CMS",
1250  "+ Polycone: startPhi=%10.3f [rad] deltaPhi=%10.3f [rad] %4ld z-planes and %4ld radii",
1251  startPhi,
1252  deltaPhi,
1253  z.size(),
1254  r.size());
1255 
1256 #endif
1257 
1258  ns.addSolid(nam, Polycone(startPhi, deltaPhi, r, z));
1259  }
1260 }
1261 
1263 template <>
1264 void Converter<DDLExtrudedPolygon>::operator()(xml_h element) const {
1265  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1266  xml_dim_t e(element);
1267  string nam = e.nameStr();
1268  vector<double> pt_x, pt_y, sec_x, sec_y, sec_z, sec_scale;
1269 
1270  for (xml_coll_t sec(element, DD_CMU(ZXYSection)); sec; ++sec) {
1271  sec_z.emplace_back(ns.attr<double>(sec, _U(z)));
1272  sec_x.emplace_back(ns.attr<double>(sec, _U(x)));
1273  sec_y.emplace_back(ns.attr<double>(sec, _U(y)));
1274  sec_scale.emplace_back(ns.attr<double>(sec, DD_CMU(scale), 1.0));
1275  }
1276  for (xml_coll_t pt(element, DD_CMU(XYPoint)); pt; ++pt) {
1277  pt_x.emplace_back(ns.attr<double>(pt, _U(x)));
1278  pt_y.emplace_back(ns.attr<double>(pt, _U(y)));
1279  }
1280 
1281 #ifdef EDM_ML_DEBUG
1282 
1283  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1284  "DD4CMS",
1285  "+ ExtrudedPolygon: %4ld points %4ld zxy sections",
1286  pt_x.size(),
1287  sec_z.size());
1288 
1289 #endif
1290 
1291  ns.addSolid(nam, ExtrudedPolygon(pt_x, pt_y, sec_z, sec_x, sec_y, sec_scale));
1292 }
1293 
1295 template <>
1296 void Converter<DDLPolyhedra>::operator()(xml_h element) const {
1297  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1298  xml_dim_t e(element);
1299  string nam = e.nameStr();
1300  double numSide = ns.attr<int>(e, DD_CMU(numSide));
1301  double startPhi = ns.attr<double>(e, DD_CMU(startPhi));
1302  double deltaPhi = ns.attr<double>(e, DD_CMU(deltaPhi));
1303  vector<double> z, rmin, rmax;
1304 
1305  for (xml_coll_t zplane(element, DD_CMU(RZPoint)); zplane; ++zplane) {
1306  rmin.emplace_back(0.0);
1307  rmax.emplace_back(ns.attr<double>(zplane, _U(r)));
1308  z.emplace_back(ns.attr<double>(zplane, _U(z)));
1309  }
1310  for (xml_coll_t zplane(element, DD_CMU(ZSection)); zplane; ++zplane) {
1311  rmin.emplace_back(ns.attr<double>(zplane, DD_CMU(rMin)));
1312  rmax.emplace_back(ns.attr<double>(zplane, DD_CMU(rMax)));
1313  z.emplace_back(ns.attr<double>(zplane, _U(z)));
1314  }
1315 
1316 #ifdef EDM_ML_DEBUG
1317 
1318  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1319  "DD4CMS",
1320  "+ Polyhedra:startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] %4d sides %4ld z-planes",
1321  startPhi,
1322  deltaPhi,
1323  numSide,
1324  z.size());
1325 
1326 #endif
1327 
1328  ns.addSolid(nam, Polyhedra(numSide, startPhi, deltaPhi, z, rmin, rmax));
1329 }
1330 
1332 template <>
1333 void Converter<DDLSphere>::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 rinner = ns.attr<double>(e, DD_CMU(innerRadius));
1338  double router = ns.attr<double>(e, DD_CMU(outerRadius));
1339  double startPhi = ns.attr<double>(e, DD_CMU(startPhi));
1340  double deltaPhi = ns.attr<double>(e, DD_CMU(deltaPhi));
1341  double startTheta = ns.attr<double>(e, DD_CMU(startTheta));
1342  double deltaTheta = ns.attr<double>(e, DD_CMU(deltaTheta));
1343 
1344 #ifdef EDM_ML_DEBUG
1345 
1346  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1347  "DD4CMS",
1348  "+ Sphere: r_inner=%8.3f [cm] r_outer=%8.3f [cm]"
1349  " startPhi=%8.3f [rad] deltaPhi=%8.3f startTheta=%8.3f delteTheta=%8.3f [rad]",
1350  rinner / dd4hep::cm,
1351  router / dd4hep::cm,
1352  startPhi,
1353  deltaPhi,
1354  startTheta,
1355  deltaTheta);
1356 
1357 #endif
1358 
1359  ns.addSolid(nam, Sphere(rinner, router, startTheta, deltaTheta, startPhi, deltaPhi));
1360 }
1361 
1363 template <>
1364 void Converter<DDLTorus>::operator()(xml_h element) const {
1365  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1366  xml_dim_t e(element);
1367  string nam = e.nameStr();
1368  double r = ns.attr<double>(e, DD_CMU(torusRadius));
1369  double rinner = ns.attr<double>(e, DD_CMU(innerRadius));
1370  double router = ns.attr<double>(e, DD_CMU(outerRadius));
1371  double startPhi = ns.attr<double>(e, DD_CMU(startPhi));
1372  double deltaPhi = ns.attr<double>(e, DD_CMU(deltaPhi));
1373 
1374 #ifdef EDM_ML_DEBUG
1375 
1376  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1377  "DD4CMS",
1378  "+ Torus: r=%10.3f [cm] r_inner=%10.3f [cm] r_outer=%10.3f [cm]"
1379  " startPhi=%10.3f [rad] deltaPhi=%10.3f [rad]",
1380  r / dd4hep::cm,
1381  rinner / dd4hep::cm,
1382  router / dd4hep::cm,
1383  startPhi,
1384  deltaPhi);
1385 
1386 #endif
1387 
1388  ns.addSolid(nam, Torus(r, rinner, router, startPhi, deltaPhi));
1389 }
1390 
1392 template <>
1393 void Converter<DDLPseudoTrap>::operator()(xml_h element) const {
1394  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1395  xml_dim_t e(element);
1396  string nam = e.nameStr();
1397  double dx1 = ns.attr<double>(e, DD_CMU(dx1));
1398  double dy1 = ns.attr<double>(e, DD_CMU(dy1));
1399  double dx2 = ns.attr<double>(e, DD_CMU(dx2));
1400  double dy2 = ns.attr<double>(e, DD_CMU(dy2));
1401  double dz = ns.attr<double>(e, _U(dz));
1402  double r = ns.attr<double>(e, _U(radius));
1403  bool atMinusZ = ns.attr<bool>(e, DD_CMU(atMinusZ));
1404 
1405 #ifdef EDM_ML_DEBUG
1406 
1407  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1408  "DD4CMS",
1409  "+ Pseudotrap: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2=%.3f dy2=%.3f radius:%.3f atMinusZ:%s",
1410  dz / dd4hep::cm,
1411  dx1 / dd4hep::cm,
1412  dy1 / dd4hep::cm,
1413  dx2 / dd4hep::cm,
1414  dy2 / dd4hep::cm,
1415  r / dd4hep::cm,
1416  yes_no(atMinusZ));
1417 
1418 #endif
1419 
1420  ns.addSolid(nam, PseudoTrap(dx1, dx2, dy1, dy2, dz, r, atMinusZ));
1421 }
1422 
1424 template <>
1425 void Converter<DDLTrapezoid>::operator()(xml_h element) const {
1426  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1427  xml_dim_t e(element);
1428  string nam = e.nameStr();
1429  double dz = ns.attr<double>(e, _U(dz));
1430  double alp1 = ns.attr<double>(e, DD_CMU(alp1));
1431  double bl1 = ns.attr<double>(e, DD_CMU(bl1));
1432  double tl1 = ns.attr<double>(e, DD_CMU(tl1));
1433  double h1 = ns.attr<double>(e, DD_CMU(h1));
1434  double alp2 = ns.attr<double>(e, DD_CMU(alp2));
1435  double bl2 = ns.attr<double>(e, DD_CMU(bl2));
1436  double tl2 = ns.attr<double>(e, DD_CMU(tl2));
1437  double h2 = ns.attr<double>(e, DD_CMU(h2));
1438  double phi = ns.attr<double>(e, _U(phi), 0.0);
1439  double theta = ns.attr<double>(e, _U(theta), 0.0);
1440 
1441 #ifdef EDM_ML_DEBUG
1442 
1443  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1444  "DD4CMS",
1445  "+ Trapezoid: dz=%10.3f [cm] alp1:%.3f bl1=%.3f tl1=%.3f alp2=%.3f bl2=%.3f tl2=%.3f h2=%.3f phi=%.3f "
1446  "theta=%.3f",
1447  dz / dd4hep::cm,
1448  alp1,
1449  bl1 / dd4hep::cm,
1450  tl1 / dd4hep::cm,
1451  h1 / dd4hep::cm,
1452  alp2,
1453  bl2 / dd4hep::cm,
1454  tl2 / dd4hep::cm,
1455  h2 / dd4hep::cm,
1456  phi,
1457  theta);
1458 
1459 #endif
1460 
1461  ns.addSolid(nam, Trap(dz, theta, phi, h1, bl1, tl1, alp1, h2, bl2, tl2, alp2));
1462 }
1463 
1465 template <>
1466 void Converter<DDLTrd1>::operator()(xml_h element) const {
1467  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1468  xml_dim_t e(element);
1469  string nam = e.nameStr();
1470  double dx1 = ns.attr<double>(e, DD_CMU(dx1));
1471  double dy1 = ns.attr<double>(e, DD_CMU(dy1));
1472  double dx2 = ns.attr<double>(e, DD_CMU(dx2), 0.0);
1473  double dy2 = ns.attr<double>(e, DD_CMU(dy2), dy1);
1474  double dz = ns.attr<double>(e, DD_CMU(dz));
1475  if (dy1 == dy2) {
1476 #ifdef EDM_ML_DEBUG
1477 
1478  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1479  "DD4CMS",
1480  "+ Trd1: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1481  dz / dd4hep::cm,
1482  dx1 / dd4hep::cm,
1483  dy1 / dd4hep::cm,
1484  dx2 / dd4hep::cm,
1485  dy2 / dd4hep::cm);
1486 
1487 #endif
1488 
1489  ns.addSolid(nam, Trd1(dx1, dx2, dy1, dz));
1490  } else {
1491 #ifdef EDM_ML_DEBUG
1492 
1493  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1494  "DD4CMS",
1495  "+ Trd1(which is actually Trd2): dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1496  dz / dd4hep::cm,
1497  dx1 / dd4hep::cm,
1498  dy1 / dd4hep::cm,
1499  dx2 / dd4hep::cm,
1500  dy2 / dd4hep::cm);
1501 
1502 #endif
1503 
1504  ns.addSolid(nam, Trd2(dx1, dx2, dy1, dy2, dz));
1505  }
1506 }
1507 
1509 template <>
1510 void Converter<DDLTrd2>::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 dx1 = ns.attr<double>(e, DD_CMU(dx1));
1515  double dy1 = ns.attr<double>(e, DD_CMU(dy1));
1516  double dx2 = ns.attr<double>(e, DD_CMU(dx2), 0.0);
1517  double dy2 = ns.attr<double>(e, DD_CMU(dy2), dy1);
1518  double dz = ns.attr<double>(e, DD_CMU(dz));
1519 
1520 #ifdef EDM_ML_DEBUG
1521 
1522  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1523  "DD4CMS",
1524  "+ Trd1: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1525  dz / dd4hep::cm,
1526  dx1 / dd4hep::cm,
1527  dy1 / dd4hep::cm,
1528  dx2 / dd4hep::cm,
1529  dy2 / dd4hep::cm);
1530 
1531 #endif
1532 
1533  ns.addSolid(nam, Trd2(dx1, dx2, dy1, dy2, dz));
1534 }
1535 
1537 template <>
1538 void Converter<DDLTubs>::operator()(xml_h element) const {
1539  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1540  xml_dim_t e(element);
1541  string nam = e.nameStr();
1542  double dz = ns.attr<double>(e, DD_CMU(dz));
1543  double rmin = ns.attr<double>(e, DD_CMU(rMin));
1544  double rmax = ns.attr<double>(e, DD_CMU(rMax));
1545  double startPhi = ns.attr<double>(e, DD_CMU(startPhi), 0.0);
1546  double deltaPhi = ns.attr<double>(e, DD_CMU(deltaPhi), 2 * M_PI);
1547 
1548 #ifdef EDM_ML_DEBUG
1549 
1550  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1551  "DD4CMS",
1552  "+ Tubs: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
1553  " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]",
1554  dz / dd4hep::cm,
1555  rmin / dd4hep::cm,
1556  rmax / dd4hep::cm,
1557  startPhi,
1558  deltaPhi);
1559 
1560 #endif
1561 
1562  ns.addSolid(nam, Tube(rmin, rmax, dz, startPhi, startPhi + deltaPhi));
1563 }
1564 
1566 template <>
1567 void Converter<DDLCutTubs>::operator()(xml_h element) const {
1568  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1569  xml_dim_t e(element);
1570  string nam = e.nameStr();
1571  double dz = ns.attr<double>(e, DD_CMU(dz));
1572  double rmin = ns.attr<double>(e, DD_CMU(rMin));
1573  double rmax = ns.attr<double>(e, DD_CMU(rMax));
1574  double startPhi = ns.attr<double>(e, DD_CMU(startPhi));
1575  double deltaPhi = ns.attr<double>(e, DD_CMU(deltaPhi));
1576  double lx = ns.attr<double>(e, DD_CMU(lx));
1577  double ly = ns.attr<double>(e, DD_CMU(ly));
1578  double lz = ns.attr<double>(e, DD_CMU(lz));
1579  double tx = ns.attr<double>(e, DD_CMU(tx));
1580  double ty = ns.attr<double>(e, DD_CMU(ty));
1581  double tz = ns.attr<double>(e, DD_CMU(tz));
1582 
1583 #ifdef EDM_ML_DEBUG
1584 
1585  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1586  "DD4CMS",
1587  "+ CutTube: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
1588  " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]...",
1589  dz / dd4hep::cm,
1590  rmin / dd4hep::cm,
1591  rmax / dd4hep::cm,
1592  startPhi,
1593  deltaPhi);
1594 
1595 #endif
1596 
1597  ns.addSolid(nam, CutTube(rmin, rmax, dz, startPhi, startPhi + deltaPhi, lx, ly, lz, tx, ty, tz));
1598 }
1599 
1601 template <>
1602 void Converter<DDLTruncTubs>::operator()(xml_h element) const {
1603  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1604  xml_dim_t e(element);
1605  string nam = e.nameStr();
1606  double zhalf = ns.attr<double>(e, DD_CMU(zHalf));
1607  double rmin = ns.attr<double>(e, DD_CMU(rMin));
1608  double rmax = ns.attr<double>(e, DD_CMU(rMax));
1609  double startPhi = ns.attr<double>(e, DD_CMU(startPhi));
1610  double deltaPhi = ns.attr<double>(e, DD_CMU(deltaPhi));
1611  double cutAtStart = ns.attr<double>(e, DD_CMU(cutAtStart));
1612  double cutAtDelta = ns.attr<double>(e, DD_CMU(cutAtDelta));
1613  bool cutInside = ns.attr<bool>(e, DD_CMU(cutInside));
1614 
1615 #ifdef EDM_ML_DEBUG
1616 
1617  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1618  "DD4CMS",
1619  "+ TruncTube:zHalf=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
1620  " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] atStart=%8.3f [cm] atDelta=%8.3f [cm] inside:%s",
1621  zhalf / dd4hep::cm,
1622  rmin / dd4hep::cm,
1623  rmax / dd4hep::cm,
1624  startPhi,
1625  deltaPhi,
1626  cutAtStart / dd4hep::cm,
1627  cutAtDelta / dd4hep::cm,
1628  yes_no(cutInside));
1629 
1630 #endif
1631 
1632  ns.addSolid(nam, TruncatedTube(zhalf, rmin, rmax, startPhi, deltaPhi, cutAtStart, cutAtDelta, cutInside));
1633 }
1634 
1636 template <>
1637 void Converter<DDLEllipticalTube>::operator()(xml_h element) const {
1638  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1639  xml_dim_t e(element);
1640  string nam = e.nameStr();
1641  double dx = ns.attr<double>(e, DD_CMU(xSemiAxis));
1642  double dy = ns.attr<double>(e, DD_CMU(ySemiAxis));
1643  double dz = ns.attr<double>(e, DD_CMU(zHeight));
1644 
1645 #ifdef EDM_ML_DEBUG
1646 
1647  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1648  "DD4CMS",
1649  "+ EllipticalTube xSemiAxis=%8.3f [cm] ySemiAxis=%8.3f [cm] zHeight=%8.3f [cm]",
1650  dx / dd4hep::cm,
1651  dy / dd4hep::cm,
1652  dz / dd4hep::cm);
1653 
1654 #endif
1655 
1656  ns.addSolid(nam, EllipticalTube(dx, dy, dz));
1657 }
1658 
1660 template <>
1661 void Converter<DDLCone>::operator()(xml_h element) const {
1662  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1663  xml_dim_t e(element);
1664  string nam = e.nameStr();
1665  double dz = ns.attr<double>(e, DD_CMU(dz));
1666  double rmin1 = ns.attr<double>(e, DD_CMU(rMin1));
1667  double rmin2 = ns.attr<double>(e, DD_CMU(rMin2));
1668  double rmax1 = ns.attr<double>(e, DD_CMU(rMax1));
1669  double rmax2 = ns.attr<double>(e, DD_CMU(rMax2));
1670  double startPhi = ns.attr<double>(e, DD_CMU(startPhi));
1671  double deltaPhi = ns.attr<double>(e, DD_CMU(deltaPhi));
1672  double phi2 = startPhi + deltaPhi;
1673 
1674 #ifdef EDM_ML_DEBUG
1675 
1676  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1677  "DD4CMS",
1678  "+ Cone: dz=%8.3f [cm]"
1679  " rmin1=%8.3f [cm] rmax1=%8.3f [cm]"
1680  " rmin2=%8.3f [cm] rmax2=%8.3f [cm]"
1681  " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]",
1682  dz / dd4hep::cm,
1683  rmin1 / dd4hep::cm,
1684  rmax1 / dd4hep::cm,
1685  rmin2 / dd4hep::cm,
1686  rmax2 / dd4hep::cm,
1687  startPhi,
1688  deltaPhi);
1689 
1690 #endif
1691 
1692  ns.addSolid(nam, ConeSegment(dz, rmin1, rmax1, rmin2, rmax2, startPhi, phi2));
1693 }
1694 
1696 template <>
1697 void Converter<DDLShapeless>::operator()(xml_h element) const {
1698  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1699  xml_dim_t e(element);
1700  string nam = e.nameStr();
1701 
1702 #ifdef EDM_ML_DEBUG
1703 
1704  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1705  "DD4CMS",
1706  "+ Shapeless: THIS ONE CAN ONLY BE USED AT THE VOLUME LEVEL -> Shapeless: %s",
1707  nam.c_str());
1708 
1709 #endif
1710 
1711  ns.addSolid(nam, Box(1, 1, 1));
1712 }
1713 
1715 template <>
1716 void Converter<DDLAssembly>::operator()(xml_h element) const {
1717  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1718  xml_dim_t e(element);
1719  string nam = e.nameStr();
1720 
1721 #ifdef EDM_ML_DEBUG
1722  printout(
1723  ns.context()->debug_shapes ? ALWAYS : DEBUG, "DD4CMS", "+ Assembly: Adding solid -> Assembly: %s", nam.c_str());
1724 #endif
1725 
1726  ns.addAssemblySolid(nam);
1727 }
1728 
1730 template <>
1731 void Converter<DDLBox>::operator()(xml_h element) const {
1732  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1733  xml_dim_t e(element);
1734  string nam = e.nameStr();
1735  double dx = ns.attr<double>(e, DD_CMU(dx));
1736  double dy = ns.attr<double>(e, DD_CMU(dy));
1737  double dz = ns.attr<double>(e, DD_CMU(dz));
1738 
1739 #ifdef EDM_ML_DEBUG
1740 
1741  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG,
1742  "DD4CMS",
1743  "+ Box: dx=%10.3f [cm] dy=%10.3f [cm] dz=%10.3f [cm]",
1744  dx / dd4hep::cm,
1745  dy / dd4hep::cm,
1746  dz / dd4hep::cm);
1747 
1748 #endif
1749 
1750  ns.addSolid(nam, Box(dx, dy, dz));
1751 }
1752 
1754 template <>
1755 void Converter<include_load>::operator()(xml_h element) const {
1756  string fname = element.attr<string>(_U(ref));
1758  xml::Document doc;
1759  doc = xml::DocumentHandler().load(fp.fullPath());
1760 
1761 #ifdef EDM_ML_DEBUG
1762 
1763  printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS : DEBUG,
1764  "DD4CMS",
1765  "+++ Processing the CMS detector description %s",
1766  fname.c_str());
1767 
1768 #endif
1769 
1770  _option<DDRegistry>()->includes.emplace_back(doc);
1771 }
1772 
1774 template <>
1775 void Converter<include_unload>::operator()(xml_h element) const {
1776  string fname = xml::DocumentHandler::system_path(element);
1777  xml::DocumentHolder(xml_elt_t(element).document()).assign(nullptr);
1778 
1779 #ifdef EDM_ML_DEBUG
1780 
1781  printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS : DEBUG,
1782  "DD4CMS",
1783  "+++ Finished processing %s",
1784  fname.c_str());
1785 #endif
1786 }
1787 
1789 template <>
1790 void Converter<include_constants>::operator()(xml_h element) const {
1791  xml_coll_t(element, DD_CMU(ConstantsSection)).for_each(Converter<ConstantsSection>(description, param, optional));
1792 }
1793 
1794 namespace {
1795 
1796  // The meaning of the axis index is the following:
1797  // for all volumes having shapes like box, trd1, trd2, trap, gtra or para - 1,2,3 means X,Y,Z;
1798  // for tube, tubs, cone, cons - 1 means Rxy, 2 means phi and 3 means Z;
1799  // for pcon and pgon - 2 means phi and 3 means Z;
1800  // for spheres 1 means R and 2 means phi.
1801 
1802  enum class DDAxes { x = 1, y = 2, z = 3, rho = 1, phi = 2, undefined };
1803  const std::map<std::string, DDAxes> axesmap{{"x", DDAxes::x},
1804  {"y", DDAxes::y},
1805  {"z", DDAxes::z},
1806  {"rho", DDAxes::rho},
1807  {"phi", DDAxes::phi},
1808  {"undefined", DDAxes::undefined}};
1809 } // namespace
1810 
1812 template <>
1813 void Converter<DDLDivision>::operator()(xml_h element) const {
1814  cms::DDNamespace ns(_param<cms::DDParsingContext>(), element);
1815  xml_dim_t e(element);
1816  string childName = e.nameStr();
1817  if (strchr(childName.c_str(), NAMESPACE_SEP) == nullptr)
1818  childName = ns.prepend(childName);
1819 
1820  string parentName = ns.attr<string>(e, DD_CMU(parent));
1821  if (strchr(parentName.c_str(), NAMESPACE_SEP) == nullptr)
1822  parentName = ns.prepend(parentName);
1823  string axis = ns.attr<string>(e, DD_CMU(axis));
1824 
1825  // If you divide a tube of 360 degrees the offset displaces
1826  // the starting angle, but you still fill the 360 degrees
1827  double offset = e.hasAttr(DD_CMU(offset)) ? ns.attr<double>(e, DD_CMU(offset)) : 0e0;
1828  double width = e.hasAttr(DD_CMU(width)) ? ns.attr<double>(e, DD_CMU(width)) : 0e0;
1829  int nReplicas = e.hasAttr(DD_CMU(nReplicas)) ? ns.attr<int>(e, DD_CMU(nReplicas)) : 0;
1830 
1831 #ifdef EDM_ML_DEBUG
1832 
1833  printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
1834  "DD4CMS",
1835  "+++ Start executing Division of %s along %s (%d) with offset %6.3f and %6.3f to produce %s....",
1836  parentName.c_str(),
1837  axis.c_str(),
1838  axesmap.at(axis),
1839  offset,
1840  width,
1841  childName.c_str());
1842 
1843 #endif
1844 
1845  Volume parent = ns.volume(parentName);
1846 
1847  const TGeoShape* shape = parent.solid();
1848  TClass* cl = shape->IsA();
1849  if (cl == TGeoTubeSeg::Class()) {
1850  const TGeoTubeSeg* sh = (const TGeoTubeSeg*)shape;
1851  double widthInDeg = convertRadToDeg(width);
1852  double startInDeg = convertRadToDeg(offset);
1853  int numCopies = (int)((sh->GetPhi2() - sh->GetPhi1()) / widthInDeg);
1854 
1855 #ifdef EDM_ML_DEBUG
1856 
1857  printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
1858  "DD4CMS",
1859  "+++ ...divide %s along %s (%d) with offset %6.3f deg and %6.3f deg to produce %d copies",
1860  parent.solid().type(),
1861  axis.c_str(),
1862  axesmap.at(axis),
1863  startInDeg,
1864  widthInDeg,
1865  numCopies);
1866 
1867 #endif
1868 
1869  Volume child = parent.divide(childName, static_cast<int>(axesmap.at(axis)), numCopies, startInDeg, widthInDeg);
1870 
1871  ns.context()->volumes[childName] = child;
1872 
1873 #ifdef EDM_ML_DEBUG
1874 
1875  printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
1876  "DD4CMS",
1877  "+++ %s Parent: %-24s [%s] Child: %-32s [%s] is multivolume [%s]",
1878  e.tag().c_str(),
1879  parentName.c_str(),
1880  parent.isValid() ? "VALID" : "INVALID",
1881  child.name(),
1882  child.isValid() ? "VALID" : "INVALID",
1883  child->IsVolumeMulti() ? "YES" : "NO");
1884 #endif
1885 
1886  } else if (cl == TGeoTrd1::Class()) {
1887  double dy = static_cast<const TGeoTrd1*>(shape)->GetDy();
1888 
1889 #ifdef EDM_ML_DEBUG
1890 
1891  printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
1892  "DD4CMS",
1893  "+++ ...divide %s along %s (%d) with offset %6.3f cm and %6.3f cm to produce %d copies in %6.3f",
1894  parent.solid().type(),
1895  axis.c_str(),
1896  axesmap.at(axis),
1897  -dy + offset + width,
1898  width,
1899  nReplicas,
1900  dy);
1901 
1902 #endif
1903 
1904  Volume child = parent.divide(childName, static_cast<int>(axesmap.at(axis)), nReplicas, -dy + offset + width, width);
1905 
1906  ns.context()->volumes[childName] = child;
1907 
1908 #ifdef EDM_ML_DEBUG
1909 
1910  printout(ns.context()->debug_placements ? ALWAYS : DEBUG,
1911  "DD4CMS",
1912  "+++ %s Parent: %-24s [%s] Child: %-32s [%s] is multivolume [%s]",
1913  e.tag().c_str(),
1914  parentName.c_str(),
1915  parent.isValid() ? "VALID" : "INVALID",
1916  child.name(),
1917  child.isValid() ? "VALID" : "INVALID",
1918  child->IsVolumeMulti() ? "YES" : "NO");
1919 
1920 #endif
1921  } else {
1922  printout(ERROR, "DD4CMS", "++ FAILED Division of a %s is not implemented yet!", parent.solid().type());
1923  }
1924 }
1925 
1927 template <>
1928 void Converter<DDLAlgorithm>::operator()(xml_h element) const {
1929  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1930  xml_dim_t e(element);
1931  string name = e.nameStr();
1932  size_t idx;
1933  string type = "DDCMS_" + ns.realName(name);
1934  while ((idx = type.find(NAMESPACE_SEP)) != string::npos)
1935  type[idx] = '_';
1936 
1937 #ifdef EDM_ML_DEBUG
1938 
1939  printout(
1940  ns.context()->debug_algorithms ? ALWAYS : DEBUG, "DD4CMS", "+++ Start executing algorithm %s....", type.c_str());
1941 
1942 #endif
1943 
1944  long ret = PluginService::Create<long>(type, &description, ns.context(), &element);
1945  if (ret == s_executed) {
1946 #ifdef EDM_ML_DEBUG
1947 
1948  printout(ns.context()->debug_algorithms ? ALWAYS : DEBUG,
1949 
1950  "DD4CMS",
1951  "+++ Executed algorithm: %08lX = %s",
1952  ret,
1953  name.c_str());
1954 
1955 #endif
1956  return;
1957  }
1958  printout(ERROR, "DD4CMS", "++ FAILED NOT ADDING SUBDETECTOR %08lX = %s", ret, name.c_str());
1959 }
1960 
1961 template <class InputIt, class ForwardIt, class BinOp>
1962 void for_each_token(InputIt first, InputIt last, ForwardIt s_first, ForwardIt s_last, BinOp binary_op) {
1963  while (first != last) {
1964  const auto pos = std::find_first_of(first, last, s_first, s_last);
1965  binary_op(first, pos);
1966  if (pos == last)
1967  break;
1968  first = std::next(pos);
1969  }
1970 }
1971 
1972 namespace {
1973 
1974  std::vector<string> splitString(const string& str, const string& delims = ",") {
1975  std::vector<string> output;
1976 
1977  for_each_token(cbegin(str), cend(str), cbegin(delims), cend(delims), [&output](auto first, auto second) {
1978  if (first != second) {
1979  if (string(first, second).front() == '[' && string(first, second).back() == ']') {
1980  first++;
1981  second--;
1982  }
1983  output.emplace_back(string(first, second));
1984  }
1985  });
1986  return output;
1987  }
1988 
1989  std::vector<double> splitNumeric(const string& str, const string& delims = ",") {
1990  std::vector<double> output;
1991 
1992  for_each_token(cbegin(str), cend(str), cbegin(delims), cend(delims), [&output](auto first, auto second) {
1993  if (first != second) {
1994  if (string(first, second).front() == '[' && string(first, second).back() == ']') {
1995  first++;
1996  second--;
1997  }
1998  output.emplace_back(dd4hep::_toDouble(string(first, second)));
1999  }
2000  });
2001  return output;
2002  }
2003 } // namespace
2004 
2007 template <>
2008 void Converter<DDLVector>::operator()(xml_h element) const {
2009  cms::DDNamespace ns(_param<cms::DDParsingContext>());
2010  cms::DDParsingContext* const context = ns.context();
2011  DDVectorsMap* registry = context->description.extension<DDVectorsMap>();
2012  xml_dim_t e(element);
2013  string name = ns.prepend(e.nameStr());
2014  string type = ns.attr<string>(e, _U(type));
2015  string nEntries = ns.attr<string>(e, DD_CMU(nEntries));
2016  string val = e.text();
2017  val.erase(remove_if(val.begin(), val.end(), [](unsigned char x) { return isspace(x); }), val.end());
2018 
2019 #ifdef EDM_ML_DEBUG
2020 
2021  printout(ns.context()->debug_constants ? ALWAYS : DEBUG,
2022  "DD4CMS",
2023  "+++ Vector<%s>: %s[%s]: %s",
2024  type.c_str(),
2025  name.c_str(),
2026  nEntries.c_str(),
2027  val.c_str());
2028 
2029 #endif
2030 
2031  try {
2032  std::vector<double> results = splitNumeric(val);
2033  registry->insert(
2034  {name,
2035  results}); //tbb::concurrent_vector<double, tbb::cache_aligned_allocator<double>>(results.begin(), results.end())});
2036  } catch (const exception& e) {
2037 #ifdef EDM_ML_DEBUG
2038 
2039  printout(INFO,
2040  "DD4CMS",
2041  "++ Unresolved Vector<%s>: %s[%s]: %s. Try to resolve later. [%s]",
2042  type.c_str(),
2043  name.c_str(),
2044  nEntries.c_str(),
2045  val.c_str(),
2046  e.what());
2047 
2048 #endif
2049 
2050  std::vector<string> results = splitString(val);
2051  context->unresolvedVectors.insert({name, results});
2052  }
2053 }
2054 
2055 template <>
2056 void Converter<debug>::operator()(xml_h dbg) const {
2057  cms::DDNamespace ns(_param<cms::DDParsingContext>());
2058  if (dbg.hasChild(DD_CMU(debug_constants)))
2059  ns.setContext()->debug_constants = true;
2060  if (dbg.hasChild(DD_CMU(debug_materials)))
2061  ns.setContext()->debug_materials = true;
2062  if (dbg.hasChild(DD_CMU(debug_rotations)))
2063  ns.setContext()->debug_rotations = true;
2064  if (dbg.hasChild(DD_CMU(debug_shapes)))
2065  ns.setContext()->debug_shapes = true;
2066  if (dbg.hasChild(DD_CMU(debug_volumes)))
2067  ns.setContext()->debug_volumes = true;
2068  if (dbg.hasChild(DD_CMU(debug_placements)))
2069  ns.setContext()->debug_placements = true;
2070  if (dbg.hasChild(DD_CMU(debug_namespaces)))
2071  ns.setContext()->debug_namespaces = true;
2072  if (dbg.hasChild(DD_CMU(debug_includes)))
2073  ns.setContext()->debug_includes = true;
2074  if (dbg.hasChild(DD_CMU(debug_algorithms)))
2075  ns.setContext()->debug_algorithms = true;
2076  if (dbg.hasChild(DD_CMU(debug_specpars)))
2077  ns.setContext()->debug_specpars = true;
2078 }
2079 
2080 template <>
2081 void Converter<DDRegistry>::operator()(xml_h /* element */) const {
2082  cms::DDParsingContext* context = _param<cms::DDParsingContext>();
2083  DDRegistry* res = _option<DDRegistry>();
2085  int count = 0;
2086 
2087 #ifdef EDM_ML_DEBUG
2088 
2089  printout(context->debug_constants ? ALWAYS : DEBUG,
2090  "DD4CMS",
2091  "+++ RESOLVING %ld unknown constants..... (out of %ld)",
2092  res->unresolvedConst.size(),
2093  res->originalConst.size());
2094 #endif
2095 
2096  while (!res->unresolvedConst.empty()) {
2097  for (auto& i : res->unresolvedConst) {
2098  const string& n = i.first;
2099  string rep;
2100  string& v = i.second;
2101  size_t idx, idq;
2102  for (idx = v.find('[', 0); idx != string::npos; idx = v.find('[', idx + 1)) {
2103  idq = v.find(']', idx + 1);
2104  rep = v.substr(idx + 1, idq - idx - 1);
2105  auto r = res->originalConst.find(rep);
2106  if (r != res->originalConst.end()) {
2107  rep = "(" + (*r).second + ")";
2108  v.replace(idx, idq - idx + 1, rep);
2109  }
2110  }
2111  if (v.find(']') == string::npos) {
2112  if (v.find("-+") != string::npos || v.find("+-") != string::npos) {
2113  while ((idx = v.find("-+")) != string::npos)
2114  v.replace(idx, 2, "-");
2115  while ((idx = v.find("+-")) != string::npos)
2116  v.replace(idx, 2, "-");
2117  }
2118 
2119 #ifdef EDM_ML_DEBUG
2120 
2121  printout(context->debug_constants ? ALWAYS : DEBUG,
2122  "DD4CMS",
2123  "+++ [%06ld] ---------- %-40s = %s",
2124  res->unresolvedConst.size() - 1,
2125  n.c_str(),
2126  res->originalConst[n].c_str());
2127 
2128 #endif
2129 
2130  ns.addConstantNS(n, v, "number");
2131  res->unresolvedConst.erase(n);
2132  break;
2133  }
2134  }
2135  if (++count > 10000)
2136  break;
2137  }
2138  if (!res->unresolvedConst.empty()) {
2139  for (const auto& e : res->unresolvedConst)
2140  printout(ERROR, "DD4CMS", "+++ Unresolved constant: %-40s = %s.", e.first.c_str(), e.second.c_str());
2141  except("DD4CMS", "++ FAILED to resolve %ld constant entries:", res->unresolvedConst.size());
2142  }
2143  res->unresolvedConst.clear();
2144  res->originalConst.clear();
2145 }
2146 
2147 template <>
2148 void Converter<print_xml_doc>::operator()(xml_h element) const {
2149  string fname = xml::DocumentHandler::system_path(element);
2150 
2151 #ifdef EDM_ML_DEBUG
2152 
2153  printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS : DEBUG,
2154  "DD4CMS",
2155  "+++ Processing data from: %s",
2156  fname.c_str());
2157 
2158 #endif
2159 }
2160 
2162 static long load_dddefinition(Detector& det, xml_h element) {
2163  xml_elt_t dddef(element);
2164  if (dddef) {
2165  cms::DDParsingContext& context = *det.extension<DDParsingContext>();
2167  ns.addConstantNS("world_x", "101*m", "number");
2168  ns.addConstantNS("world_y", "101*m", "number");
2169  ns.addConstantNS("world_z", "450*m", "number");
2170  ns.addConstantNS("Air", "materials:Air", "string");
2171  ns.addConstantNS("Vacuum", "materials:Vacuum", "string");
2172 
2173  string fname = xml::DocumentHandler::system_path(element);
2174  bool open_geometry = dddef.hasChild(DD_CMU(open_geometry)) ? dddef.child(DD_CMU(open_geometry)) : true;
2175  bool close_geometry = dddef.hasChild(DD_CMU(close_geometry)) ? dddef.hasChild(DD_CMU(close_geometry)) : true;
2176 
2177  xml_coll_t(dddef, _U(debug)).for_each(Converter<debug>(det, &context));
2178 
2179  // Here we define the order how XML elements are processed.
2180  // Be aware of dependencies. This can only defined once.
2181  // At the end it is a limitation of DOM....
2182  printout(INFO, "DD4CMS", "+++ Processing the CMS detector description %s", fname.c_str());
2183 
2184  xml::Document doc;
2185  Converter<print_xml_doc> print_doc(det, &context);
2186  try {
2187  DDRegistry res;
2188  res.unresolvedConst.reserve(2000);
2189  res.originalConst.reserve(6000);
2190  print_doc((doc = dddef.document()).root());
2191  xml_coll_t(dddef, DD_CMU(ConstantsSection)).for_each(Converter<ConstantsSection>(det, &context, &res));
2192  xml_coll_t(dddef, DD_CMU(RotationSection)).for_each(Converter<RotationSection>(det, &context));
2193  xml_coll_t(dddef, DD_CMU(MaterialSection)).for_each(Converter<MaterialSection>(det, &context));
2194 
2195  xml_coll_t(dddef, DD_CMU(IncludeSection)).for_each(DD_CMU(Include), Converter<include_load>(det, &context, &res));
2196 
2197  for (xml::Document d : res.includes) {
2198  print_doc((doc = d).root());
2199  Converter<include_constants>(det, &context, &res)((doc = d).root());
2200  }
2201  // Before we continue, we have to resolve all constants NOW!
2202  Converter<DDRegistry>(det, &context, &res)(dddef);
2203  {
2204  DDVectorsMap* registry = context.description.extension<DDVectorsMap>();
2205 
2206  printout(context.debug_constants ? ALWAYS : DEBUG,
2207  "DD4CMS",
2208  "+++ RESOLVING %ld Vectors.....",
2209  context.unresolvedVectors.size());
2210 
2211  while (!context.unresolvedVectors.empty()) {
2212  for (auto it = context.unresolvedVectors.begin(); it != context.unresolvedVectors.end();) {
2213  std::vector<double> result;
2214  for (const auto& i : it->second) {
2215  result.emplace_back(dd4hep::_toDouble(i));
2216  }
2217  registry->insert({it->first, result});
2218  // All components are resolved
2219  it = context.unresolvedVectors.erase(it);
2220  }
2221  }
2222  }
2223  // Now we can process the include files one by one.....
2224  for (xml::Document d : res.includes) {
2225  print_doc((doc = d).root());
2226  xml_coll_t(d.root(), DD_CMU(MaterialSection)).for_each(Converter<MaterialSection>(det, &context));
2227  }
2228  if (open_geometry) {
2229  det.init();
2230  ns.addVolume(det.worldVolume());
2231  }
2232  for (xml::Document d : res.includes) {
2233  print_doc((doc = d).root());
2234  xml_coll_t(d.root(), DD_CMU(RotationSection)).for_each(Converter<RotationSection>(det, &context));
2235  }
2236  for (xml::Document d : res.includes) {
2237  print_doc((doc = d).root());
2238  xml_coll_t(d.root(), DD_CMU(SolidSection)).for_each(Converter<SolidSection>(det, &context));
2239  }
2240  for (xml::Document d : res.includes) {
2241  print_doc((doc = d).root());
2242  xml_coll_t(d.root(), DD_CMU(LogicalPartSection)).for_each(Converter<LogicalPartSection>(det, &context));
2243  }
2244  for (xml::Document d : res.includes) {
2245  print_doc((doc = d).root());
2246  xml_coll_t(d.root(), DD_CMU(Algorithm)).for_each(Converter<DDLAlgorithm>(det, &context));
2247  }
2248  for (xml::Document d : res.includes) {
2249  print_doc((doc = d).root());
2250  xml_coll_t(d.root(), DD_CMU(PosPartSection)).for_each(Converter<PosPartSection>(det, &context));
2251  }
2252  for (xml::Document d : res.includes) {
2253  print_doc((doc = d).root());
2254  xml_coll_t(d.root(), DD_CMU(SpecParSection)).for_each(Converter<SpecParSection>(det, &context));
2255  }
2256 
2258  for (xml::Document d : res.includes)
2259  Converter<include_unload>(det, &context, &res)(d.root());
2260 
2261  print_doc((doc = dddef.document()).root());
2262  // Now process the actual geometry items
2263  xml_coll_t(dddef, DD_CMU(SolidSection)).for_each(Converter<SolidSection>(det, &context));
2264  {
2265  // Before we continue, we have to resolve all shapes NOW!
2266  // Note: This only happens in a legacy DB payloads where
2267  // boolean shapes can be defined before thier
2268  // component shapes
2269 
2270  while (!context.unresolvedShapes.empty()) {
2271  for (auto it = context.unresolvedShapes.begin(); it != context.unresolvedShapes.end();) {
2272  auto const& name = it->first;
2273  auto const& aname = std::visit([](auto&& arg) -> std::string { return arg.firstSolidName; }, it->second);
2274  auto const& bname = std::visit([](auto&& arg) -> std::string { return arg.secondSolidName; }, it->second);
2275 
2276  auto const& ait = context.shapes.find(aname);
2277  if (ait->second.isValid()) {
2278  auto const& bit = context.shapes.find(bname);
2279  if (bit->second.isValid()) {
2280  dd4hep::Solid shape =
2281  std::visit([&ait, &bit](auto&& arg) -> dd4hep::Solid { return arg.make(ait->second, bit->second); },
2282  it->second);
2283  context.shapes[name] = shape;
2284  it = context.unresolvedShapes.erase(it);
2285  } else
2286  ++it;
2287  } else
2288  ++it;
2289  }
2290  }
2291  }
2292  xml_coll_t(dddef, DD_CMU(LogicalPartSection)).for_each(Converter<LogicalPartSection>(det, &context));
2293  xml_coll_t(dddef, DD_CMU(Algorithm)).for_each(Converter<DDLAlgorithm>(det, &context));
2294  xml_coll_t(dddef, DD_CMU(PosPartSection)).for_each(Converter<PosPartSection>(det, &context));
2295  xml_coll_t(dddef, DD_CMU(SpecParSection)).for_each(Converter<SpecParSection>(det, &context));
2296  } catch (const exception& e) {
2297  printout(ERROR, "DD4CMS", "Exception while processing xml source:%s", doc.uri().c_str());
2298  printout(ERROR, "DD4CMS", "----> %s", e.what());
2299  throw;
2300  }
2301 
2303  if (close_geometry) {
2304  Volume wv = det.worldVolume();
2305  Volume geomv = ns.volume("cms:OCMS", false);
2306  if (geomv.isValid())
2307  wv.placeVolume(geomv, 1);
2308  Volume mfv = ns.volume("cmsMagneticField:MAGF", false);
2309  if (mfv.isValid())
2310  wv.placeVolume(mfv, 1);
2311  Volume mfv1 = ns.volume("MagneticFieldVolumes:MAGF", false);
2312  if (mfv1.isValid())
2313  wv.placeVolume(mfv1, 1);
2314 
2315  // Can not deal with reflections without closed geometry
2316  det.manager().CloseGeometry("nv");
2317 
2318  det.endDocument();
2319  }
2320  printout(INFO, "DDDefinition", "+++ Finished processing %s", fname.c_str());
2321  return 1;
2322  }
2323  except("DDDefinition", "+++ FAILED to process unknown DOM tree [Invalid Handle]");
2324  return 0;
2325 }
2326 
2327 // Now declare the factory entry for the plugin mechanism
2328 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
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:245
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:13
DDLLogicalPart processes LogicalPart elements.
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
results
Definition: mysort.py:8
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
Definition: output.py:1
#define str(s)
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
SOARotation< float > Rotation
#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)