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"
12 #include "XML/Utilities.h"
21 #include "TGeoManager.h"
22 #include "TGeoMaterial.h"
29 #include "tbb/concurrent_unordered_map.h"
30 #include "tbb/concurrent_vector.h"
41 atomic<UInt_t> unique_mat_id = 0xAFFEFEED;
44 class include_constants;
49 class ConstantsSection;
53 tbb::concurrent_vector<xml::Document>
includes;
57 class MaterialSection;
61 class RotationSection;
63 class DDLReflectionRotation;
72 class LogicalPartSection;
76 class DDLExtrudedPolygon;
93 class DDLIntersectionSolid;
94 class DDLSubtractionSolid;
115 TGeoTranslation
t(iTrans.x(), iTrans.y(), iTrans.z());
117 return new TGeoCombiTrans(
t,
r);
122 void Converter<debug>::operator()(xml_h element)
const;
124 void Converter<print_xml_doc>::operator()(xml_h element)
const;
126 void Converter<disabled_algo>::operator()(xml_h element)
const;
130 void Converter<ConstantsSection>::operator()(xml_h element)
const;
132 void Converter<DDLConstant>::operator()(xml_h element)
const;
134 void Converter<DDRegistry>::operator()(xml_h element)
const;
138 void Converter<vissection>::operator()(xml_h element)
const;
141 void Converter<vis>::operator()(xml_h element)
const;
145 void Converter<MaterialSection>::operator()(xml_h element)
const;
147 void Converter<DDLElementaryMaterial>::operator()(xml_h element)
const;
149 void Converter<DDLCompositeMaterial>::operator()(xml_h element)
const;
153 void Converter<RotationSection>::operator()(xml_h element)
const;
156 void Converter<DDLRotation>::operator()(xml_h element)
const;
159 void Converter<DDLReflectionRotation>::operator()(xml_h element)
const;
162 void Converter<DDLRotationSequence>::operator()(xml_h element)
const;
165 void Converter<DDLRotationByAxis>::operator()(xml_h element)
const;
167 void Converter<DDLTransform3D>::operator()(xml_h element)
const;
171 void Converter<LogicalPartSection>::operator()(xml_h element)
const;
173 void Converter<DDLLogicalPart>::operator()(xml_h element)
const;
177 void Converter<PosPartSection>::operator()(xml_h element)
const;
180 void Converter<DDLPosPart>::operator()(xml_h element)
const;
183 void Converter<DDLDivision>::operator()(xml_h element)
const;
187 void Converter<SpecParSection>::operator()(xml_h element)
const;
189 void Converter<SpecPar>::operator()(xml_h element)
const;
191 void Converter<PartSelector>::operator()(xml_h element)
const;
193 void Converter<Parameter>::operator()(xml_h element)
const;
197 void Converter<SolidSection>::operator()(xml_h element)
const;
200 void Converter<DDLUnionSolid>::operator()(xml_h element)
const;
203 void Converter<DDLSubtractionSolid>::operator()(xml_h element)
const;
206 void Converter<DDLIntersectionSolid>::operator()(xml_h element)
const;
209 void Converter<DDLPseudoTrap>::operator()(xml_h element)
const;
212 void Converter<DDLExtrudedPolygon>::operator()(xml_h element)
const;
215 void Converter<DDLShapeless>::operator()(xml_h element)
const;
218 void Converter<DDLTrapezoid>::operator()(xml_h element)
const;
221 void Converter<DDLPolycone>::operator()(xml_h element)
const;
224 void Converter<DDLPolyhedra>::operator()(xml_h element)
const;
227 void Converter<DDLEllipticalTube>::operator()(xml_h element)
const;
230 void Converter<DDLTorus>::operator()(xml_h element)
const;
233 void Converter<DDLTubs>::operator()(xml_h element)
const;
236 void Converter<DDLCutTubs>::operator()(xml_h element)
const;
239 void Converter<DDLTruncTubs>::operator()(xml_h element)
const;
242 void Converter<DDLSphere>::operator()(xml_h element)
const;
245 void Converter<DDLTrd1>::operator()(xml_h element)
const;
248 void Converter<DDLTrd2>::operator()(xml_h element)
const;
251 void Converter<DDLCone>::operator()(xml_h element)
const;
254 void Converter<DDLBox>::operator()(xml_h element)
const;
257 void Converter<DDLAlgorithm>::operator()(xml_h element)
const;
260 void Converter<DDLVector>::operator()(xml_h element)
const;
264 void Converter<include_load>::operator()(xml_h element)
const;
267 void Converter<include_unload>::operator()(xml_h element)
const;
270 void Converter<include_constants>::operator()(xml_h element)
const;
275 void Converter<ConstantsSection>::operator()(xml_h element)
const {
284 void Converter<vissection>::operator()(xml_h element)
const {
291 void Converter<MaterialSection>::operator()(xml_h element)
const {
293 xml_coll_t(element,
DD_CMU(ElementaryMaterial))
295 xml_coll_t(element,
DD_CMU(CompositeMaterial))
300 void Converter<RotationSection>::operator()(xml_h element)
const {
303 xml_coll_t(element,
DD_CMU(ReflectionRotation))
305 xml_coll_t(element,
DD_CMU(RotationSequence))
307 xml_coll_t(element,
DD_CMU(RotationByAxis))
312 void Converter<PosPartSection>::operator()(xml_h element)
const {
320 void Converter<SpecParSection>::operator()(xml_h element)
const {
326 void Converter<SpecPar>::operator()(xml_h element)
const {
334 void Converter<LogicalPartSection>::operator()(xml_h element)
const {
340 void Converter<disabled_algo>::operator()(xml_h element)
const {
342 c->disabledAlgs.emplace_back(element.attr<
string>(_U(
name)));
347 void Converter<SolidSection>::operator()(xml_h element)
const {
349 for (xml_coll_t solid(element, _U(star)); solid; ++solid) {
350 string tag = solid.tag();
352 switch (
hash(solid.tag())) {
356 case hash(
"Polycone"):
359 case hash(
"Polyhedra"):
365 case hash(
"CutTubs"):
368 case hash(
"TruncTubs"):
386 case hash(
"EllipticalTube"):
392 case hash(
"PseudoTrap"):
395 case hash(
"ExtrudedPolygon"):
398 case hash(
"Trapezoid"):
401 case hash(
"UnionSolid"):
404 case hash(
"SubtractionSolid"):
407 case hash(
"IntersectionSolid"):
410 case hash(
"ShapelessSolid"):
414 throw std::runtime_error(
"Request to process unknown shape '" + xml_dim_t(solid).nameStr() +
"' [" +
tag +
"]");
422 void Converter<DDLConstant>::operator()(xml_h element)
const {
424 DDRegistry*
res = _option<DDRegistry>();
425 xml_dim_t constant = element;
426 xml_dim_t par = constant.parent();
427 bool eval = par.hasAttr(_U(eval)) ? par.attr<
bool>(_U(eval)) :
false;
428 string val = constant.valueStr();
429 string nam = constant.nameStr();
430 string real = ns.prepend(nam);
431 string typ = eval ?
"number" :
"string";
432 size_t idx =
val.find(
'[');
434 if (constant.hasAttr(_U(
type)))
435 typ = constant.typeStr();
437 if (
idx == string::npos || typ ==
"string") {
439 ns.addConstant(nam,
val, typ);
440 res->allConst[real] =
val;
441 res->originalConst[real] =
val;
445 "++ Unresolved constant: %s = %s [%s]. Try to resolve later. [%s]",
454 while (
idx != string::npos) {
456 size_t idp =
val.find(
':',
idx);
457 size_t idq =
val.find(
']',
idx);
458 if (idp == string::npos || idp > idq)
459 val.insert(
idx, ns.name());
460 else if (idp != string::npos && idp < idq)
465 ns.context()->debug_constants ? ALWAYS :
DEBUG,
"Constant",
"Unresolved: %s -> %s", real.c_str(),
val.c_str());
466 res->allConst[real] =
val;
467 res->originalConst[real] =
val;
468 res->unresolvedConst[real] =
val;
480 void Converter<vis>::operator()(xml_h
e)
const {
482 VisAttr attr(
e.attr<
string>(_U(
name)));
483 float red =
e.hasAttr(_U(
r)) ?
e.attr<
float>(_U(
r)) : 1.0
f;
484 float green =
e.hasAttr(_U(
g)) ?
e.attr<
float>(_U(
g)) : 1.0
f;
485 float blue =
e.hasAttr(_U(
b)) ?
e.attr<
float>(_U(
b)) : 1.0
f;
487 printout(ns.context()->debug_visattr ? ALWAYS :
DEBUG,
489 "++ Converting VisAttr structure: %-16s. R=%.3f G=%.3f B=%.3f",
494 attr.setColor(
red, green,
blue);
496 attr.setAlpha(
e.attr<
float>(_U(
alpha)));
497 if (
e.hasAttr(_U(visible)))
498 attr.setVisible(
e.attr<
bool>(_U(visible)));
501 if (
ls ==
"unbroken")
502 attr.setLineStyle(VisAttr::SOLID);
503 else if (
ls ==
"broken")
504 attr.setLineStyle(VisAttr::DASHED);
506 attr.setLineStyle(VisAttr::SOLID);
508 if (
e.hasAttr(_U(drawingStyle))) {
509 string ds =
e.attr<
string>(_U(drawingStyle));
510 if (ds ==
"wireframe")
511 attr.setDrawingStyle(VisAttr::WIREFRAME);
512 else if (ds ==
"solid")
513 attr.setDrawingStyle(VisAttr::SOLID);
515 attr.setDrawingStyle(VisAttr::SOLID);
517 if (
e.hasAttr(_U(showDaughters)))
518 attr.setShowDaughters(
e.attr<
bool>(_U(showDaughters)));
520 attr.setShowDaughters(
true);
526 void Converter<DDLElementaryMaterial>::operator()(xml_h element)
const {
528 xml_dim_t xmat(element);
529 string nam = ns.prepend(xmat.nameStr());
531 TGeoMaterial* mat = mgr.GetMaterial(nam.c_str());
532 if (
nullptr == mat) {
533 const char* matname = nam.c_str();
535 int atomicNumber = xmat.attr<
int>(
DD_CMU(atomicNumber));
536 double atomicWeight = xmat.attr<
double>(
DD_CMU(atomicWeight)) / (
dd4hep::g / dd4hep::mole);
537 TGeoElementTable* tab = mgr.GetElementTable();
538 int nElem = tab->GetNelements();
539 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
"DD4CMS",
"+++ Element table size = %d", nElem);
542 tab->TGeoElementTable::~TGeoElementTable();
543 new (tab) TGeoElementTable();
544 tab->BuildDefaultElements();
546 TGeoMixture*
mix =
new TGeoMixture(nam.c_str(), 1,
density);
547 TGeoElement* elt = tab->FindElement(xmat.nameStr().c_str());
548 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
550 "+++ Searching for material %-48s elt_ptr = %ld",
551 xmat.nameStr().c_str(),
554 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
556 "+++ Converting material %-48s Atomic weight %8.3f [g/mol], Atomic number %u, Density: %8.3f [g/cm3] "
557 "ROOT: %8.3f [g/cm3]",
558 (
'"' + nam +
'"').c_str(),
564 bool newMatDef =
false;
568 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
570 " ROOT definition of %-50s Atomic weight %g, Atomic number %u, Number of nucleons %u",
575 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
577 "+++ Compared to XML values: Atomic weight %g, Atomic number %u",
580 static const double weightTolerance = 1.0e-6;
581 if (atomicNumber != elt->Z() ||
582 (
std::abs(atomicWeight - elt->A()) > (weightTolerance * (atomicWeight + elt->A()))))
586 if (!elt || newMatDef) {
590 "+++ Converter<ElementaryMaterial> Different definition of a default element with name:%s [CREATE NEW "
596 "+++ Converter<ElementaryMaterial> No default element present with name:%s [CREATE NEW MATERIAL]",
598 elt =
new TGeoElement(xmat.nameStr().c_str(),
"CMS element", atomicNumber, atomicWeight);
601 mix->AddElement(elt, 1.0);
604 TGeoMedium* medium = mgr.GetMedium(matname);
605 if (
nullptr == medium) {
607 medium =
new TGeoMedium(matname, unique_mat_id,
mix);
608 medium->SetTitle(
"material");
609 medium->SetUniqueID(unique_mat_id);
616 void Converter<DDLCompositeMaterial>::operator()(xml_h element)
const {
618 xml_dim_t xmat(element);
619 string nam = ns.prepend(xmat.nameStr());
622 TGeoMaterial* mat = mgr.GetMaterial(nam.c_str());
623 if (
nullptr == mat) {
624 const char* matname = nam.c_str();
626 xml_coll_t composites(xmat,
DD_CMU(MaterialFraction));
627 TGeoMixture*
mix =
new TGeoMixture(nam.c_str(), composites.size(),
density);
629 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
631 "++ Converting material %-48s Density: %8.3f [g/cm3] ROOT: %8.3f [g/cm3]",
632 (
'"' + nam +
'"').c_str(),
636 for (composites.reset(); composites; ++composites) {
637 xml_dim_t xfrac(composites);
638 xml_dim_t xfrac_mat(xfrac.child(
DD_CMU(rMaterial)));
640 string fracname = ns.realName(xfrac_mat.nameStr());
642 TGeoMaterial* frac_mat = mgr.GetMaterial(fracname.c_str());
643 if (frac_mat ==
nullptr)
644 frac_mat = mgr.GetMaterial(ns.prepend(fracname).c_str());
652 "+++ Composite material \"%s\" [nor \"%s\"] not present! [delay resolution]",
654 ns.prepend(fracname).c_str());
655 ns.context()->unresolvedMaterials[nam].emplace_back(
660 TGeoMedium* medium = mgr.GetMedium(matname);
661 if (
nullptr == medium) {
663 medium =
new TGeoMedium(matname, unique_mat_id,
mix);
664 medium->SetTitle(
"material");
665 medium->SetUniqueID(unique_mat_id);
672 void Converter<DDLRotation>::operator()(xml_h element)
const {
675 xml_dim_t xrot(element);
676 string nam = xrot.nameStr();
678 double phiX = xrot.hasAttr(
DD_CMU(phiX)) ? ns.attr<
double>(xrot,
DD_CMU(phiX)) : 0e0;
680 double phiY = xrot.hasAttr(
DD_CMU(phiY)) ? ns.attr<
double>(xrot,
DD_CMU(phiY)) : 0e0;
682 double phiZ = xrot.hasAttr(
DD_CMU(phiZ)) ? ns.attr<
double>(xrot,
DD_CMU(phiZ)) : 0e0;
686 "+++ Adding rotation: %-32s: (theta/phi)[rad] X: %6.3f %6.3f Y: %6.3f %6.3f Z: %6.3f %6.3f",
687 ns.prepend(nam).c_str(),
694 ns.addRotation(nam,
rot);
699 void Converter<DDLReflectionRotation>::operator()(xml_h element)
const {
702 xml_dim_t xrot(element);
703 string name = xrot.nameStr();
705 double phiX = xrot.hasAttr(
DD_CMU(phiX)) ? ns.attr<
double>(xrot,
DD_CMU(phiX)) : 0e0;
707 double phiY = xrot.hasAttr(
DD_CMU(phiY)) ? ns.attr<
double>(xrot,
DD_CMU(phiY)) : 0e0;
709 double phiZ = xrot.hasAttr(
DD_CMU(phiZ)) ? ns.attr<
double>(xrot,
DD_CMU(phiZ)) : 0e0;
712 "+++ Adding reflection rotation: %-32s: (theta/phi)[rad] X: %6.3f %6.3f Y: %6.3f %6.3f Z: %6.3f %6.3f",
713 ns.prepend(
name).c_str(),
726 void Converter<DDLRotationSequence>::operator()(xml_h element)
const {
729 xml_dim_t xrot(element);
730 string nam = xrot.nameStr();
732 xml_coll_t rotations(xrot,
DD_CMU(RotationByAxis));
733 for (rotations.reset(); rotations; ++rotations) {
734 string axis = ns.attr<
string>(rotations,
DD_CMU(axis));
735 double angle = ns.attr<
double>(rotations, _U(
angle));
739 "+ Adding rotation to: %-29s: (axis/angle)[rad] Axis: %s Angle: %6.3f",
750 "+++ Adding rotation sequence: %-23s: %6.3f %6.3f %6.3f, %6.3f %6.3f %6.3f, %6.3f %6.3f %6.3f",
751 ns.prepend(nam).c_str(),
761 ns.addRotation(nam,
rot);
766 void Converter<DDLRotationByAxis>::operator()(xml_h element)
const {
769 xml_dim_t xrot(element);
770 xml_dim_t par(xrot.parent());
771 if (xrot.hasAttr(_U(
name))) {
772 string nam = xrot.nameStr();
773 string axis = ns.attr<
string>(xrot,
DD_CMU(axis));
774 double angle = ns.attr<
double>(xrot, _U(
angle));
779 "+++ Adding rotation: %-32s: (axis/angle)[rad] Axis: %s Angle: %6.3f",
780 ns.prepend(nam).c_str(),
783 ns.addRotation(nam,
rot);
789 void Converter<DDLLogicalPart>::operator()(xml_h element)
const {
791 xml_dim_t
e(element);
792 string sol =
e.child(
DD_CMU(rSolid)).attr<
string>(_U(
name));
793 string mat =
e.child(
DD_CMU(rMaterial)).attr<
string>(_U(
name));
794 string volName =
e.attr<
string>(_U(
name));
795 Solid solid = ns.solid(sol);
796 Material material = ns.material(mat);
797 Volume volume = ns.addVolume(
Volume(volName, solid, material));
798 printout(ns.context()->debug_volumes ? ALWAYS :
DEBUG,
800 "+++ %s Volume: %-24s [%s] Shape: %-32s [%s] Material: %-40s [%s]",
803 volume.isValid() ?
"VALID" :
"INVALID",
805 solid.isValid() ?
"VALID" :
"INVALID",
807 material.isValid() ?
"VALID" :
"INVALID");
812 void Converter<DDLTransform3D>::operator()(xml_h element)
const {
814 Transform3D* tr = _option<Transform3D>();
815 xml_dim_t
e(element);
818 xml_dim_t refRotation =
e.child(
DD_CMU(rRotation),
false);
819 xml_dim_t refReflectionRotation =
e.child(
DD_CMU(rReflectionRotation),
false);
823 if (translation.ptr()) {
824 double x = ns.attr<
double>(translation, _U(
x));
825 double y = ns.attr<
double>(translation, _U(
y));
826 double z = ns.attr<
double>(translation, _U(
z));
833 rot = RotationZYX(
z,
y,
x);
834 }
else if (refRotation.ptr()) {
835 string rotName = ns.prepend(refRotation.nameStr());
836 rot = ns.rotation(rotName);
837 }
else if (refReflectionRotation.ptr()) {
838 string rotName = ns.prepend(refReflectionRotation.nameStr());
839 rot = ns.rotation(rotName);
841 *tr = Transform3D(
rot,
pos);
846 void Converter<DDLPosPart>::operator()(xml_h element)
const {
848 xml_dim_t
e(element);
850 string parentName = ns.attr<
string>(
e.child(
DD_CMU(rParent)), _U(
name));
851 string childName = ns.attr<
string>(
e.child(
DD_CMU(rChild)), _U(
name));
854 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
856 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] copy:%d",
859 parent.isValid() ?
"VALID" :
"INVALID",
861 child.isValid() ?
"VALID" :
"INVALID",
865 parentName = ns.prepend(parentName);
866 parent = ns.volume(parentName);
869 childName = ns.prepend(childName);
870 child = ns.volume(childName,
false);
872 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
874 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] copy:%d",
877 parent.isValid() ?
"VALID" :
"INVALID",
879 child.isValid() ?
"VALID" :
"INVALID",
883 if (
child.isValid()) {
891 except(
"dd4hep",
"Volume: Attempt to assign daughters to an invalid physical parent volume.");
894 except(
"dd4hep",
"Volume: Attempt to assign an invalid physical daughter volume.");
896 TGeoShape* shape =
child->GetShape();
899 TGeoShapeAssembly* as = (TGeoShapeAssembly*)shape;
903 as->NeedsBBoxRecompute();
908 TString nam_id = TString::Format(
"%s_%d",
child->GetName(),
copy);
909 n = static_cast<TGeoNode*>(
parent->GetNode(nam_id));
911 printout(
ERROR,
"PlacedVolume",
"++ Attempt to add already exiting node %s", (
const char*)nam_id);
915 Translation3D trans(
transform.Translation());
917 trans.GetComponents(
x,
y,
z);
921 n = static_cast<TGeoNode*>(
parent->GetNode(nam_id));
922 n->TGeoNode::SetUserExtension(
new PlacedVolume::Object());
928 "+++ Placement FAILED! Parent:%s Child:%s Valid:%s",
931 yes_no(
child.isValid()));
937 void Converter<PartSelector>::operator()(xml_h element)
const {
941 xml_dim_t
e(element);
942 xml_dim_t specPar =
e.parent();
943 string specParName = specPar.attr<
string>(_U(
name));
945 printout(ns.context()->debug_specpars ? ALWAYS :
DEBUG,
947 "+++ PartSelector for %s path: %s",
950 registry.
specpars[specParName].paths.emplace_back(
path);
955 void Converter<Parameter>::operator()(xml_h element)
const {
959 xml_dim_t
e(element);
960 xml_dim_t specPar =
e.parent();
961 xml_dim_t specParSect = specPar.parent();
962 string specParName = specPar.attr<
string>(_U(
name));
963 string name =
e.nameStr();
965 bool eval =
e.hasAttr(_U(eval)) ?
e.attr<
bool>(_U(eval))
966 : (specParSect.hasAttr(_U(eval)) ? specParSect.attr<
bool>(_U(eval)) :
false);
967 string type = eval ?
"number" :
"string";
969 printout(ns.context()->debug_specpars ? ALWAYS :
DEBUG,
971 "+++ Parameter for %s: %s value %s is a %s",
978 if (
idx == string::npos ||
type ==
"string") {
983 while (
idx != string::npos) {
987 if (idp == string::npos || idp > idq)
989 else if (idp != string::npos && idp < idq)
997 for (
idx =
v.find(
'[', 0);
idx != string::npos;
idx =
v.find(
'[',
idx + 1)) {
998 idq =
v.find(
']',
idx + 1);
1000 auto r = ns.context()->description.load()->constants().find(
rep);
1001 if (
r != ns.context()->description.load()->constants().end()) {
1002 rep =
"(" +
r->second->type +
")";
1009 template <
typename TYPE>
1012 xml_dim_t
e(element);
1013 string nam =
e.nameStr();
1014 string solidName[2];
1018 if (
e.hasChild(
DD_CMU(rSolid))) {
1019 for (xml_coll_t
c(element,
DD_CMU(rSolid)); cnt < 2 &&
c; ++
c, ++cnt) {
1020 solidName[cnt] =
c.attr<
string>(_U(
name));
1021 solids[cnt] = ns.
solid(
c.attr<
string>(_U(
name)));
1024 solidName[0] =
e.attr<
string>(
DD_CMU(firstSolid));
1025 if ((solids[0] = ns.
solid(
e.attr<
string>(
DD_CMU(firstSolid)))).isValid())
1027 solidName[1] =
e.attr<
string>(
DD_CMU(secondSolid));
1028 if ((solids[1] = ns.
solid(
e.attr<
string>(
DD_CMU(secondSolid)))).isValid())
1032 except(
"DD4CMS",
"+++ Failed to create boolean solid %s. Found only %d parts.", nam.c_str(), cnt);
1037 "+++ BooleanSolid: %s Left: %-32s Right: %-32s",
1039 ((solids[0].ptr() ==
nullptr) ? solidName[0].c_str() : solids[0]->GetName()),
1040 ((solids[1].ptr() ==
nullptr) ? solidName[1].c_str() : solids[1]->GetName()));
1042 if (solids[0].isValid() && solids[1].isValid()) {
1044 Converter<DDLTransform3D>(*context->
description, context, &trafo)(element);
1045 boolean =
TYPE(solids[0], solids[1], trafo);
1049 Converter<DDLTransform3D>(*context->
description, context, &trafo)(element);
1053 if (!
boolean.isValid()) {
1062 void Converter<DDLUnionSolid>::operator()(xml_h element)
const {
1063 convert_boolean<UnionSolid>(_param<cms::DDParsingContext>(), element);
1068 void Converter<DDLSubtractionSolid>::operator()(xml_h element)
const {
1069 convert_boolean<SubtractionSolid>(_param<cms::DDParsingContext>(), element);
1074 void Converter<DDLIntersectionSolid>::operator()(xml_h element)
const {
1075 convert_boolean<IntersectionSolid>(_param<cms::DDParsingContext>(), element);
1080 void Converter<DDLPolycone>::operator()(xml_h element)
const {
1082 xml_dim_t
e(element);
1083 string nam =
e.nameStr();
1084 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1086 vector<double>
z, rmin, rmax,
r;
1088 for (xml_coll_t rzpoint(element,
DD_CMU(RZPoint)); rzpoint; ++rzpoint) {
1089 z.emplace_back(ns.attr<
double>(rzpoint, _U(
z)));
1090 r.emplace_back(ns.attr<
double>(rzpoint, _U(
r)));
1093 for (xml_coll_t zplane(element,
DD_CMU(ZSection)); zplane; ++zplane) {
1094 rmin.emplace_back(ns.attr<
double>(zplane,
DD_CMU(
rMin)));
1095 rmax.emplace_back(ns.attr<
double>(zplane,
DD_CMU(
rMax)));
1096 z.emplace_back(ns.attr<
double>(zplane, _U(
z)));
1098 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1100 "+ Polycone: startPhi=%10.3f [rad] deltaPhi=%10.3f [rad] %4ld z-planes",
1104 ns.addSolid(nam, Polycone(startPhi,
deltaPhi, rmin, rmax,
z));
1106 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1108 "+ Polycone: startPhi=%10.3f [rad] deltaPhi=%10.3f [rad] %4ld z-planes and %4ld radii",
1113 ns.addSolid(nam, Polycone(startPhi,
deltaPhi,
r,
z));
1119 void Converter<DDLExtrudedPolygon>::operator()(xml_h element)
const {
1121 xml_dim_t
e(element);
1122 string nam =
e.nameStr();
1123 vector<double> pt_x, pt_y, sec_x, sec_y, sec_z, sec_scale;
1126 sec_z.emplace_back(ns.attr<
double>(
sec, _U(
z)));
1127 sec_x.emplace_back(ns.attr<
double>(
sec, _U(
x)));
1128 sec_y.emplace_back(ns.attr<
double>(
sec, _U(
y)));
1129 sec_scale.emplace_back(ns.attr<
double>(
sec,
DD_CMU(
scale), 1.0));
1131 for (xml_coll_t
pt(element,
DD_CMU(XYPoint));
pt; ++
pt) {
1132 pt_x.emplace_back(ns.attr<
double>(
pt, _U(
x)));
1133 pt_y.emplace_back(ns.attr<
double>(
pt, _U(
y)));
1135 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1137 "+ ExtrudedPolygon: %4ld points %4ld zxy sections",
1140 ns.addSolid(nam,
ExtrudedPolygon(pt_x, pt_y, sec_z, sec_x, sec_y, sec_scale));
1145 void Converter<DDLPolyhedra>::operator()(xml_h element)
const {
1147 xml_dim_t
e(element);
1148 string nam =
e.nameStr();
1149 double numSide = ns.attr<
int>(
e,
DD_CMU(numSide));
1150 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1152 vector<double>
z, rmin, rmax;
1154 for (xml_coll_t zplane(element,
DD_CMU(RZPoint)); zplane; ++zplane) {
1155 rmin.emplace_back(0.0);
1156 rmax.emplace_back(ns.attr<
double>(zplane, _U(
r)));
1157 z.emplace_back(ns.attr<
double>(zplane, _U(
z)));
1159 for (xml_coll_t zplane(element,
DD_CMU(ZSection)); zplane; ++zplane) {
1160 rmin.emplace_back(ns.attr<
double>(zplane,
DD_CMU(
rMin)));
1161 rmax.emplace_back(ns.attr<
double>(zplane,
DD_CMU(
rMax)));
1162 z.emplace_back(ns.attr<
double>(zplane, _U(
z)));
1164 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1166 "+ Polyhedra:startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] %4d sides %4ld z-planes",
1176 void Converter<DDLSphere>::operator()(xml_h element)
const {
1178 xml_dim_t
e(element);
1179 string nam =
e.nameStr();
1182 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1184 double startTheta = ns.attr<
double>(
e,
DD_CMU(startTheta));
1185 double deltaTheta = ns.attr<
double>(
e,
DD_CMU(deltaTheta));
1186 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1188 "+ Sphere: r_inner=%8.3f [cm] r_outer=%8.3f [cm]"
1189 " startPhi=%8.3f [rad] deltaPhi=%8.3f startTheta=%8.3f delteTheta=%8.3f [rad]",
1196 ns.addSolid(nam, Sphere(rinner, router, startTheta, deltaTheta, startPhi,
deltaPhi));
1201 void Converter<DDLTorus>::operator()(xml_h element)
const {
1203 xml_dim_t
e(element);
1204 string nam =
e.nameStr();
1205 double r = ns.attr<
double>(
e,
DD_CMU(torusRadius));
1208 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1210 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1212 "+ Torus: r=%10.3f [cm] r_inner=%10.3f [cm] r_outer=%10.3f [cm]"
1213 " startPhi=%10.3f [rad] deltaPhi=%10.3f [rad]",
1219 ns.addSolid(nam, Torus(
r, rinner, router, startPhi,
deltaPhi));
1224 void Converter<DDLPseudoTrap>::operator()(xml_h element)
const {
1226 xml_dim_t
e(element);
1227 string nam =
e.nameStr();
1228 double dx1 = ns.attr<
double>(
e,
DD_CMU(dx1));
1229 double dy1 = ns.attr<
double>(
e,
DD_CMU(dy1));
1230 double dx2 = ns.attr<
double>(
e,
DD_CMU(dx2));
1231 double dy2 = ns.attr<
double>(
e,
DD_CMU(dy2));
1232 double dz = ns.attr<
double>(
e, _U(
dz));
1233 double r = ns.attr<
double>(
e, _U(
radius));
1234 bool atMinusZ = ns.attr<
bool>(
e,
DD_CMU(atMinusZ));
1235 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1237 "+ Pseudotrap: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2=%.3f dy2=%.3f radius:%.3f atMinusZ:%s",
1245 ns.addSolid(nam, PseudoTrap(dx1, dx2, dy1, dy2,
dz,
r, atMinusZ));
1250 void Converter<DDLTrapezoid>::operator()(xml_h element)
const {
1252 xml_dim_t
e(element);
1253 string nam =
e.nameStr();
1254 double dz = ns.attr<
double>(
e, _U(
dz));
1255 double alp1 = ns.attr<
double>(
e,
DD_CMU(alp1));
1256 double bl1 = ns.attr<
double>(
e,
DD_CMU(bl1));
1257 double tl1 = ns.attr<
double>(
e,
DD_CMU(tl1));
1258 double h1 = ns.attr<
double>(
e,
DD_CMU(h1));
1259 double alp2 = ns.attr<
double>(
e,
DD_CMU(alp2));
1260 double bl2 = ns.attr<
double>(
e,
DD_CMU(bl2));
1261 double tl2 = ns.attr<
double>(
e,
DD_CMU(tl2));
1262 double h2 = ns.attr<
double>(
e,
DD_CMU(h2));
1263 double phi = ns.attr<
double>(
e, _U(
phi), 0.0);
1264 double theta = ns.attr<
double>(
e, _U(
theta), 0.0);
1266 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1268 "+ Trapezoid: dz=%10.3f [cm] alp1:%.3f bl1=%.3f tl1=%.3f alp2=%.3f bl2=%.3f tl2=%.3f h2=%.3f phi=%.3f "
1281 ns.addSolid(nam, Trap(
dz,
theta,
phi, h1, bl1, tl1, alp1, h2, bl2, tl2, alp2));
1286 void Converter<DDLTrd1>::operator()(xml_h element)
const {
1288 xml_dim_t
e(element);
1289 string nam =
e.nameStr();
1290 double dx1 = ns.attr<
double>(
e,
DD_CMU(dx1));
1291 double dy1 = ns.attr<
double>(
e,
DD_CMU(dy1));
1292 double dx2 = ns.attr<
double>(
e,
DD_CMU(dx2), 0.0);
1293 double dy2 = ns.attr<
double>(
e,
DD_CMU(dy2), dy1);
1296 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1298 "+ Trd1: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1304 ns.addSolid(nam, Trd1(dx1, dx2, dy1,
dz));
1306 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1308 "+ Trd1(which is actually Trd2): dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1314 ns.addSolid(nam, Trd2(dx1, dx2, dy1, dy2,
dz));
1320 void Converter<DDLTrd2>::operator()(xml_h element)
const {
1322 xml_dim_t
e(element);
1323 string nam =
e.nameStr();
1324 double dx1 = ns.attr<
double>(
e,
DD_CMU(dx1));
1325 double dy1 = ns.attr<
double>(
e,
DD_CMU(dy1));
1326 double dx2 = ns.attr<
double>(
e,
DD_CMU(dx2), 0.0);
1327 double dy2 = ns.attr<
double>(
e,
DD_CMU(dy2), dy1);
1329 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1331 "+ Trd1: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1337 ns.addSolid(nam, Trd2(dx1, dx2, dy1, dy2,
dz));
1342 void Converter<DDLTubs>::operator()(xml_h element)
const {
1344 xml_dim_t
e(element);
1345 string nam =
e.nameStr();
1349 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi), 0.0);
1351 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1353 "+ Tubs: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
1354 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]",
1360 ns.addSolid(nam, Tube(rmin, rmax,
dz, startPhi, startPhi +
deltaPhi));
1365 void Converter<DDLCutTubs>::operator()(xml_h element)
const {
1367 xml_dim_t
e(element);
1368 string nam =
e.nameStr();
1372 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1374 double lx = ns.attr<
double>(
e,
DD_CMU(lx));
1375 double ly = ns.attr<
double>(
e,
DD_CMU(ly));
1376 double lz = ns.attr<
double>(
e,
DD_CMU(lz));
1377 double tx = ns.attr<
double>(
e,
DD_CMU(tx));
1378 double ty = ns.attr<
double>(
e,
DD_CMU(ty));
1379 double tz = ns.attr<
double>(
e,
DD_CMU(tz));
1380 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1382 "+ CutTube: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
1383 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]...",
1389 ns.addSolid(nam, CutTube(rmin, rmax,
dz, startPhi, startPhi +
deltaPhi, lx, ly, lz, tx, ty, tz));
1394 void Converter<DDLTruncTubs>::operator()(xml_h element)
const {
1396 xml_dim_t
e(element);
1397 string nam =
e.nameStr();
1398 double zhalf = ns.attr<
double>(
e,
DD_CMU(zHalf));
1401 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1403 double cutAtStart = ns.attr<
double>(
e,
DD_CMU(cutAtStart));
1404 double cutAtDelta = ns.attr<
double>(
e,
DD_CMU(cutAtDelta));
1405 bool cutInside = ns.attr<
bool>(
e,
DD_CMU(cutInside));
1406 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1408 "+ TruncTube:zHalf=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
1409 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] atStart=%8.3f [cm] atDelta=%8.3f [cm] inside:%s",
1418 ns.addSolid(nam, TruncatedTube(zhalf, rmin, rmax, startPhi,
deltaPhi, cutAtStart, cutAtDelta, cutInside));
1423 void Converter<DDLEllipticalTube>::operator()(xml_h element)
const {
1425 xml_dim_t
e(element);
1426 string nam =
e.nameStr();
1427 double dx = ns.attr<
double>(
e,
DD_CMU(xSemiAxis));
1428 double dy = ns.attr<
double>(
e,
DD_CMU(ySemiAxis));
1429 double dz = ns.attr<
double>(
e,
DD_CMU(zHeight));
1430 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1432 "+ EllipticalTube xSemiAxis=%8.3f [cm] ySemiAxis=%8.3f [cm] zHeight=%8.3f [cm]",
1436 ns.addSolid(nam, EllipticalTube(
dx,
dy,
dz));
1441 void Converter<DDLCone>::operator()(xml_h element)
const {
1443 xml_dim_t
e(element);
1444 string nam =
e.nameStr();
1446 double rmin1 = ns.attr<
double>(
e,
DD_CMU(rMin1));
1447 double rmin2 = ns.attr<
double>(
e,
DD_CMU(rMin2));
1448 double rmax1 = ns.attr<
double>(
e,
DD_CMU(rMax1));
1449 double rmax2 = ns.attr<
double>(
e,
DD_CMU(rMax2));
1450 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1453 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1455 "+ Cone: dz=%8.3f [cm]"
1456 " rmin1=%8.3f [cm] rmax1=%8.3f [cm]"
1457 " rmin2=%8.3f [cm] rmax2=%8.3f [cm]"
1458 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]",
1466 ns.addSolid(nam, ConeSegment(
dz, rmin1, rmax1, rmin2, rmax2, startPhi, phi2));
1471 void Converter<DDLShapeless>::operator()(xml_h element)
const {
1473 xml_dim_t
e(element);
1474 string nam =
e.nameStr();
1475 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1477 "+ Shapeless: THIS ONE CAN ONLY BE USED AT THE VOLUME LEVEL -> Assembly%s",
1479 ns.addSolid(nam, Box(1, 1, 1));
1484 void Converter<DDLBox>::operator()(xml_h element)
const {
1486 xml_dim_t
e(element);
1487 string nam =
e.nameStr();
1491 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1493 "+ Box: dx=%10.3f [cm] dy=%10.3f [cm] dz=%10.3f [cm]",
1497 ns.addSolid(nam, Box(
dx,
dy,
dz));
1502 void Converter<include_load>::operator()(xml_h element)
const {
1503 string fname = element.attr<
string>(_U(ref));
1506 doc = xml::DocumentHandler().load(
fp.fullPath());
1507 printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS :
DEBUG,
1509 "+++ Processing the CMS detector description %s",
1511 _option<DDRegistry>()->includes.emplace_back(
doc);
1516 void Converter<include_unload>::operator()(xml_h element)
const {
1517 string fname = xml::DocumentHandler::system_path(element);
1518 xml::DocumentHolder(xml_elt_t(element).document()).assign(
nullptr);
1519 printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS :
DEBUG,
1521 "+++ Finished processing %s",
1527 void Converter<include_constants>::operator()(xml_h element)
const {
1540 const std::map<std::string, DDAxes> axesmap{{
"x",
DDAxes::x},
1550 void Converter<DDLDivision>::operator()(xml_h element)
const {
1552 xml_dim_t
e(element);
1553 string childName =
e.nameStr();
1555 childName = ns.prepend(childName);
1559 parentName = ns.prepend(parentName);
1560 string axis = ns.attr<
string>(
e,
DD_CMU(axis));
1566 int nReplicas =
e.hasAttr(
DD_CMU(nReplicas)) ? ns.attr<
int>(
e,
DD_CMU(nReplicas)) : 0;
1568 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1570 "+++ Start executing Division of %s along %s (%d) with offset %6.3f and %6.3f to produce %s....",
1580 const TGeoShape* shape =
parent.solid();
1581 TClass*
cl = shape->IsA();
1583 const TGeoTubeSeg* sh = (
const TGeoTubeSeg*)shape;
1586 int numCopies = (
int)((sh->GetPhi2() - sh->GetPhi1()) / widthInDeg);
1587 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1589 "+++ ...divide %s along %s (%d) with offset %6.3f deg and %6.3f deg to produce %d copies",
1596 Volume child =
parent.divide(childName, static_cast<int>(axesmap.at(axis)), numCopies, startInDeg, widthInDeg);
1598 ns.context()->volumes[childName] =
child;
1600 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1602 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] is multivolume [%s]",
1605 parent.isValid() ?
"VALID" :
"INVALID",
1607 child.isValid() ?
"VALID" :
"INVALID",
1608 child->IsVolumeMulti() ?
"YES" :
"NO");
1611 double dy = static_cast<const TGeoTrd1*>(shape)->GetDy();
1612 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1614 "+++ ...divide %s along %s (%d) with offset %6.3f cm and %6.3f cm to produce %d copies in %6.3f",
1624 ns.context()->volumes[childName] =
child;
1626 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1628 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] is multivolume [%s]",
1631 parent.isValid() ?
"VALID" :
"INVALID",
1633 child.isValid() ?
"VALID" :
"INVALID",
1634 child->IsVolumeMulti() ?
"YES" :
"NO");
1636 printout(
ERROR,
"DD4CMS",
"++ FAILED Division of a %s is not implemented yet!",
parent.solid().type());
1642 void Converter<DDLAlgorithm>::operator()(xml_h element)
const {
1644 xml_dim_t
e(element);
1645 string name =
e.nameStr();
1646 for (
auto const&
i : ns.context()->disabledAlgs) {
1649 printout(
INFO,
"DD4CMS",
"+++ Skip disabled algorithms: %s",
name.c_str());
1656 string type =
"DDCMS_" + ns.realName(
name);
1663 ns.context()->debug_algorithms ? ALWAYS :
DEBUG,
"DD4CMS",
"+++ Start executing algorithm %s....",
type.c_str());
1667 printout(ns.context()->debug_algorithms ? ALWAYS :
DEBUG,
1669 "+++ Executed algorithm: %08lX = %s",
1674 printout(
ERROR,
"DD4CMS",
"++ FAILED NOT ADDING SUBDETECTOR %08lX = %s",
ret,
name.c_str());
1677 template <
class InputIt,
class ForwardIt,
class BinOp>
1680 const auto pos = std::find_first_of(
first,
last, s_first, s_last);
1690 std::vector<string>
splitString(
const string&
str,
const string& delims =
",") {
1691 std::vector<string>
output;
1705 tbb::concurrent_vector<double> splitNumeric(
const string&
str,
const string& delims =
",") {
1706 tbb::concurrent_vector<double>
output;
1724 void Converter<DDLVector>::operator()(xml_h element)
const {
1728 xml_dim_t
e(element);
1729 string name = ns.prepend(
e.nameStr());
1730 string type = ns.attr<
string>(
e, _U(
type));
1731 string nEntries = ns.attr<
string>(
e,
DD_CMU(nEntries));
1732 string val =
e.text();
1733 val.erase(remove_if(
val.begin(),
val.end(), [](
unsigned char x) {
return isspace(x); }),
val.end());
1735 printout(ns.context()->debug_constants ? ALWAYS :
DEBUG,
1737 "+++ Vector<%s>: %s[%s]: %s",
1743 tbb::concurrent_vector<double>
results = splitNumeric(
val);
1748 "++ Unresolved Vector<%s>: %s[%s]: %s. Try to resolve later. [%s]",
1761 void Converter<debug>::operator()(xml_h dbg)
const {
1763 if (dbg.hasChild(
DD_CMU(debug_visattr)))
1764 ns.setContext()->debug_visattr =
true;
1765 if (dbg.hasChild(
DD_CMU(debug_constants)))
1766 ns.setContext()->debug_constants =
true;
1767 if (dbg.hasChild(
DD_CMU(debug_materials)))
1768 ns.setContext()->debug_materials =
true;
1769 if (dbg.hasChild(
DD_CMU(debug_rotations)))
1770 ns.setContext()->debug_rotations =
true;
1771 if (dbg.hasChild(
DD_CMU(debug_shapes)))
1772 ns.setContext()->debug_shapes =
true;
1773 if (dbg.hasChild(
DD_CMU(debug_volumes)))
1774 ns.setContext()->debug_volumes =
true;
1775 if (dbg.hasChild(
DD_CMU(debug_placements)))
1776 ns.setContext()->debug_placements =
true;
1777 if (dbg.hasChild(
DD_CMU(debug_namespaces)))
1778 ns.setContext()->debug_namespaces =
true;
1779 if (dbg.hasChild(
DD_CMU(debug_includes)))
1780 ns.setContext()->debug_includes =
true;
1781 if (dbg.hasChild(
DD_CMU(debug_algorithms)))
1782 ns.setContext()->debug_algorithms =
true;
1783 if (dbg.hasChild(
DD_CMU(debug_specpars)))
1784 ns.setContext()->debug_specpars =
true;
1788 void Converter<DDRegistry>::operator()(xml_h )
const {
1790 DDRegistry*
res = _option<DDRegistry>();
1796 "+++ RESOLVING %ld unknown constants.....",
1797 res->unresolvedConst.size());
1799 while (!
res->unresolvedConst.empty()) {
1800 for (
auto i :
res->unresolvedConst) {
1801 const string&
n =
i.first;
1803 string&
v =
i.second;
1805 for (
idx =
v.find(
'[', 0);
idx != string::npos;
idx =
v.find(
'[',
idx + 1)) {
1806 idq =
v.find(
']',
idx + 1);
1808 auto r =
res->allConst.find(
rep);
1809 if (
r !=
res->allConst.end()) {
1810 rep =
"(" + (*r).second +
")";
1814 if (
v.find(
']') == string::npos) {
1815 if (
v.find(
"-+") != string::npos ||
v.find(
"+-") != string::npos) {
1816 while ((
idx =
v.find(
"-+")) != string::npos)
1817 v.replace(
idx, 2,
"-");
1818 while ((
idx =
v.find(
"+-")) != string::npos)
1819 v.replace(
idx, 2,
"-");
1823 "+++ [%06ld] ---------- %-40s = %s",
1824 res->unresolvedConst.size() - 1,
1826 res->originalConst[
n].c_str());
1827 ns.addConstantNS(
n,
v,
"number");
1828 res->unresolvedConst.unsafe_erase(
n);
1832 if (++
count > 10000)
1835 if (!
res->unresolvedConst.empty()) {
1836 for (
const auto&
e :
res->unresolvedConst)
1837 printout(
ERROR,
"DD4CMS",
"+++ Unresolved constant: %-40s = %s.",
e.first.c_str(),
e.second.c_str());
1838 except(
"DD4CMS",
"++ FAILED to resolve %ld constant entries:",
res->unresolvedConst.size());
1840 res->unresolvedConst.clear();
1841 res->originalConst.clear();
1842 res->allConst.clear();
1846 void Converter<print_xml_doc>::operator()(xml_h element)
const {
1847 string fname = xml::DocumentHandler::system_path(element);
1848 printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS :
DEBUG,
1850 "+++ Processing data from: %s",
1866 xml_elt_t dddef(element);
1867 string fname = xml::DocumentHandler::system_path(element);
1868 bool open_geometry = dddef.hasChild(
DD_CMU(open_geometry)) ? dddef.child(
DD_CMU(open_geometry)) :
true;
1869 bool close_geometry = dddef.hasChild(
DD_CMU(close_geometry)) ? dddef.hasChild(
DD_CMU(close_geometry)) :
true;
1871 xml_coll_t(dddef, _U(
debug)).for_each(Converter<debug>(det, &context));
1876 printout(
INFO,
"DD4CMS",
"+++ Processing the CMS detector description %s",
fname.c_str());
1879 Converter<print_xml_doc> print_doc(det, &context);
1882 print_doc((
doc = dddef.document()).
root());
1883 xml_coll_t(dddef,
DD_CMU(DisabledAlgo)).for_each(Converter<disabled_algo>(det, &context, &
res));
1884 xml_coll_t(dddef,
DD_CMU(ConstantsSection)).for_each(Converter<ConstantsSection>(det, &context, &
res));
1885 xml_coll_t(dddef,
DD_CMU(VisSection)).for_each(Converter<vissection>(det, &context));
1886 xml_coll_t(dddef,
DD_CMU(RotationSection)).for_each(Converter<RotationSection>(det, &context));
1887 xml_coll_t(dddef,
DD_CMU(MaterialSection)).for_each(Converter<MaterialSection>(det, &context));
1889 xml_coll_t(dddef,
DD_CMU(IncludeSection)).for_each(
DD_CMU(Include), Converter<include_load>(det, &context, &
res));
1891 for (xml::Document
d :
res.includes) {
1893 Converter<include_constants>(det, &context, &
res)((
doc =
d).
root());
1896 Converter<DDRegistry>(det, &context, &
res)(dddef);
1902 "+++ RESOLVING %ld Vectors.....",
1907 auto const&
name = it->first;
1908 tbb::concurrent_vector<double>
result;
1909 for (
const auto&
i : it->second) {
1910 result.emplace_back(dd4hep::_toDouble(
i));
1919 for (xml::Document
d :
res.includes) {
1921 xml_coll_t(
d.root(),
DD_CMU(MaterialSection)).for_each(Converter<MaterialSection>(det, &context));
1926 "+++ RESOLVING %ld unknown material constituents.....",
1933 auto const&
name = it->first;
1934 std::vector<bool>
valid;
1938 "+++ [%06ld] ---------- %s",
1943 for (
auto& mit : it->second) {
1946 "+++ component %-48s Fraction: %.6f",
1950 if (
nullptr != fmat.ptr()) {
1951 if (mat.ptr()->GetMaterial()->IsMixture()) {
1952 valid.emplace_back(
true);
1953 static_cast<TGeoMixture*>(mat.ptr()->GetMaterial())->AddElement(fmat.ptr()->GetMaterial(), mit.fraction);
1958 if (
valid.size() == it->second.size())
1967 if (open_geometry) {
1972 for (xml::Document
d :
res.includes) {
1974 xml_coll_t(
d.root(),
DD_CMU(RotationSection)).for_each(Converter<RotationSection>(det, &context));
1976 for (xml::Document
d :
res.includes) {
1978 xml_coll_t(
d.root(),
DD_CMU(SolidSection)).for_each(Converter<SolidSection>(det, &context));
1980 for (xml::Document
d :
res.includes) {
1982 xml_coll_t(
d.root(),
DD_CMU(LogicalPartSection)).for_each(Converter<LogicalPartSection>(det, &context));
1984 for (xml::Document
d :
res.includes) {
1986 xml_coll_t(
d.root(),
DD_CMU(
Algorithm)).for_each(Converter<DDLAlgorithm>(det, &context));
1988 for (xml::Document
d :
res.includes) {
1990 xml_coll_t(
d.root(),
DD_CMU(PosPartSection)).for_each(Converter<PosPartSection>(det, &context));
1992 for (xml::Document
d :
res.includes) {
1994 xml_coll_t(
d.root(),
DD_CMU(SpecParSection)).for_each(Converter<SpecParSection>(det, &context));
1998 for (xml::Document
d :
res.includes)
1999 Converter<include_unload>(det, &context, &
res)(
d.root());
2001 print_doc((
doc = dddef.document()).
root());
2003 xml_coll_t(dddef,
DD_CMU(SolidSection)).for_each(Converter<SolidSection>(det, &context));
2012 auto const&
name = it->first;
2013 auto const& aname = std::visit([](
auto&&
arg) ->
std::string {
return arg.firstSolidName; }, it->second);
2014 auto const& bname = std::visit([](
auto&&
arg) ->
std::string {
return arg.secondSolidName; }, it->second);
2016 auto const& ait = context.
shapes.find(aname);
2017 if (ait->second.isValid()) {
2018 auto const& bit = context.
shapes.find(bname);
2019 if (bit->second.isValid()) {
2020 dd4hep::Solid shape = std::visit(
2021 [&ait, &bit](
auto&&
arg) -> dd4hep::Solid {
return arg.make(ait->second, bit->second); }, it->second);
2031 xml_coll_t(dddef,
DD_CMU(LogicalPartSection)).for_each(Converter<LogicalPartSection>(det, &context));
2032 xml_coll_t(dddef,
DD_CMU(
Algorithm)).for_each(Converter<DDLAlgorithm>(det, &context));
2033 xml_coll_t(dddef,
DD_CMU(PosPartSection)).for_each(Converter<PosPartSection>(det, &context));
2034 xml_coll_t(dddef,
DD_CMU(SpecParSection)).for_each(Converter<SpecParSection>(det, &context));
2036 printout(
ERROR,
"DD4CMS",
"Exception while processing xml source:%s",
doc.uri().c_str());
2037 printout(
ERROR,
"DD4CMS",
"----> %s",
e.what());
2042 if (close_geometry) {
2043 Volume wv = det.worldVolume();
2045 if (geomv.isValid())
2046 wv.placeVolume(geomv, 1);
2047 Volume mfv = ns.
volume(
"cmsMagneticField:MAGF",
false);
2049 wv.placeVolume(mfv, 1);
2050 Volume mfv1 = ns.
volume(
"MagneticFieldVolumes:MAGF",
false);
2052 wv.placeVolume(mfv1, 1);
2056 printout(
INFO,
"DDDefinition",
"+++ Finished processing %s",
fname.c_str());