CMS 3D CMS Logo

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