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 <unordered_map>
43 atomic<UInt_t> unique_mat_id = 0xAFFEFEED;
45 class include_constants;
50 class ConstantsSection;
59 class MaterialSection;
63 class RotationSection;
65 class DDLReflectionRotation;
74 class LogicalPartSection;
78 class DDLExtrudedPolygon;
95 class DDLIntersectionSolid;
96 class DDLSubtractionSolid;
101 class SpecParSection;
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;
128 void Converter<ConstantsSection>::operator()(xml_h element)
const;
130 void Converter<DDLConstant>::operator()(xml_h element)
const;
132 void Converter<DDRegistry>::operator()(xml_h element)
const;
136 void Converter<MaterialSection>::operator()(xml_h element)
const;
138 void Converter<DDLElementaryMaterial>::operator()(xml_h element)
const;
140 void Converter<DDLCompositeMaterial>::operator()(xml_h element)
const;
144 void Converter<RotationSection>::operator()(xml_h element)
const;
147 void Converter<DDLRotation>::operator()(xml_h element)
const;
150 void Converter<DDLReflectionRotation>::operator()(xml_h element)
const;
153 void Converter<DDLRotationSequence>::operator()(xml_h element)
const;
156 void Converter<DDLRotationByAxis>::operator()(xml_h element)
const;
158 void Converter<DDLTransform3D>::operator()(xml_h element)
const;
162 void Converter<LogicalPartSection>::operator()(xml_h element)
const;
164 void Converter<DDLLogicalPart>::operator()(xml_h element)
const;
168 void Converter<PosPartSection>::operator()(xml_h element)
const;
171 void Converter<DDLPosPart>::operator()(xml_h element)
const;
174 void Converter<DDLDivision>::operator()(xml_h element)
const;
178 void Converter<SpecParSection>::operator()(xml_h element)
const;
180 void Converter<DDLSpecPar>::operator()(xml_h element)
const;
182 void Converter<PartSelector>::operator()(xml_h element)
const;
184 void Converter<Parameter>::operator()(xml_h element)
const;
188 void Converter<SolidSection>::operator()(xml_h element)
const;
191 void Converter<DDLUnionSolid>::operator()(xml_h element)
const;
194 void Converter<DDLSubtractionSolid>::operator()(xml_h element)
const;
197 void Converter<DDLIntersectionSolid>::operator()(xml_h element)
const;
200 void Converter<DDLPseudoTrap>::operator()(xml_h element)
const;
203 void Converter<DDLExtrudedPolygon>::operator()(xml_h element)
const;
206 void Converter<DDLShapeless>::operator()(xml_h element)
const;
209 void Converter<DDLTrapezoid>::operator()(xml_h element)
const;
212 void Converter<DDLPolycone>::operator()(xml_h element)
const;
215 void Converter<DDLPolyhedra>::operator()(xml_h element)
const;
218 void Converter<DDLEllipticalTube>::operator()(xml_h element)
const;
221 void Converter<DDLTorus>::operator()(xml_h element)
const;
224 void Converter<DDLTubs>::operator()(xml_h element)
const;
227 void Converter<DDLCutTubs>::operator()(xml_h element)
const;
230 void Converter<DDLTruncTubs>::operator()(xml_h element)
const;
233 void Converter<DDLSphere>::operator()(xml_h element)
const;
236 void Converter<DDLTrd1>::operator()(xml_h element)
const;
239 void Converter<DDLTrd2>::operator()(xml_h element)
const;
242 void Converter<DDLCone>::operator()(xml_h element)
const;
245 void Converter<DDLBox>::operator()(xml_h element)
const;
248 void Converter<DDLAlgorithm>::operator()(xml_h element)
const;
251 void Converter<DDLVector>::operator()(xml_h element)
const;
255 void Converter<include_load>::operator()(xml_h element)
const;
258 void Converter<include_unload>::operator()(xml_h element)
const;
261 void Converter<include_constants>::operator()(xml_h element)
const;
266 void Converter<ConstantsSection>::operator()(xml_h element)
const {
275 void Converter<MaterialSection>::operator()(xml_h element)
const {
277 xml_coll_t(element,
DD_CMU(ElementaryMaterial))
279 xml_coll_t(element,
DD_CMU(CompositeMaterial))
284 void Converter<RotationSection>::operator()(xml_h element)
const {
287 xml_coll_t(element,
DD_CMU(ReflectionRotation))
289 xml_coll_t(element,
DD_CMU(RotationSequence))
291 xml_coll_t(element,
DD_CMU(RotationByAxis))
296 void Converter<PosPartSection>::operator()(xml_h element)
const {
304 void Converter<SpecParSection>::operator()(xml_h element)
const {
310 void Converter<DDLSpecPar>::operator()(xml_h element)
const {
318 void Converter<LogicalPartSection>::operator()(xml_h element)
const {
325 void Converter<SolidSection>::operator()(xml_h element)
const {
327 for (xml_coll_t solid(element, _U(star)); solid; ++solid) {
329 switch (
hash(solid.tag())) {
333 case hash(
"Polycone"):
336 case hash(
"Polyhedra"):
342 case hash(
"CutTubs"):
345 case hash(
"TruncTubs"):
363 case hash(
"EllipticalTube"):
369 case hash(
"PseudoTrap"):
372 case hash(
"ExtrudedPolygon"):
375 case hash(
"Trapezoid"):
378 case hash(
"UnionSolid"):
381 case hash(
"SubtractionSolid"):
384 case hash(
"IntersectionSolid"):
387 case hash(
"ShapelessSolid"):
391 throw std::runtime_error(
"Request to process unknown shape '" + xml_dim_t(solid).nameStr() +
"' [" +
400 void Converter<DDLConstant>::operator()(xml_h element)
const {
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(
'[');
412 if (constant.hasAttr(_U(
type)))
413 typ = constant.typeStr();
415 if (
idx == string::npos || typ ==
"string") {
417 ns.addConstant(nam,
val, typ);
418 res->originalConst[real] =
val;
424 "++ Unresolved constant: %s = %s [%s]. Try to resolve later. [%s]",
434 while (
idx != string::npos) {
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)
448 ns.context()->debug_constants ? ALWAYS :
DEBUG,
"Constant",
"Unresolved: %s -> %s", real.c_str(),
val.c_str());
452 res->originalConst[real] =
val;
453 res->unresolvedConst[real] =
val;
458 void Converter<DDLElementaryMaterial>::operator()(xml_h element)
const {
460 xml_dim_t xmat(element);
461 string nam = ns.prepend(xmat.nameStr());
463 TGeoMaterial* mat = mgr.GetMaterial(nam.c_str());
464 if (
nullptr == mat) {
465 const char* matname = nam.c_str();
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();
474 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
"DD4CMS",
"+++ Element table size = %d", nElem);
479 tab->TGeoElementTable::~TGeoElementTable();
480 new (tab) TGeoElementTable();
481 tab->BuildDefaultElements();
483 TGeoMixture*
mix =
new TGeoMixture(nam.c_str(), 1,
density);
484 TGeoElement* elt = tab->FindElement(xmat.nameStr().c_str());
488 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
490 "+++ Searching for material %-48s elt_ptr = %ld",
491 xmat.nameStr().c_str(),
494 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
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(),
506 bool newMatDef =
false;
513 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
515 " ROOT definition of %-50s Atomic weight %g, Atomic number %u, Number of nucleons %u",
520 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
522 "+++ Compared to XML values: Atomic weight %g, Atomic number %u",
527 static constexpr
double const weightTolerance = 1.0e-6;
528 if (atomicNumber != elt->Z() ||
529 (
std::abs(atomicWeight - elt->A()) > (weightTolerance * (atomicWeight + elt->A()))))
533 if (!elt || newMatDef) {
537 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
539 "+++ Converter<ElementaryMaterial> Different definition of a default element with name:%s [CREATE NEW "
548 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
550 "+++ Converter<ElementaryMaterial> No default element present with name:%s [CREATE NEW MATERIAL]",
555 elt =
new TGeoElement(xmat.nameStr().c_str(),
"CMS element", atomicNumber, atomicWeight);
558 mix->AddElement(elt, 1.0);
561 TGeoMedium* medium = mgr.GetMedium(matname);
562 if (
nullptr == medium) {
564 medium =
new TGeoMedium(matname, unique_mat_id,
mix);
565 medium->SetTitle(
"material");
566 medium->SetUniqueID(unique_mat_id);
573 void Converter<DDLCompositeMaterial>::operator()(xml_h element)
const {
575 xml_dim_t xmat(element);
576 string nam = ns.prepend(xmat.nameStr());
579 TGeoMaterial* mat = mgr.GetMaterial(nam.c_str());
580 if (
nullptr == mat) {
581 const char* matname = nam.c_str();
583 xml_coll_t composites(xmat,
DD_CMU(MaterialFraction));
584 TGeoMixture*
mix =
new TGeoMixture(nam.c_str(), composites.size(),
density);
588 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
590 "++ Converting material %-48s Density: %8.3f [g/cm3] ROOT: %8.3f [g/cm3]",
591 (
'"' + nam +
'"').c_str(),
597 for (composites.reset(); composites; ++composites) {
598 xml_dim_t xfrac(composites);
599 xml_dim_t xfrac_mat(xfrac.child(
DD_CMU(rMaterial)));
601 string fracname = ns.realName(xfrac_mat.nameStr());
603 TGeoMaterial* frac_mat = mgr.GetMaterial(fracname.c_str());
604 if (frac_mat ==
nullptr)
605 frac_mat = mgr.GetMaterial(ns.prepend(fracname).c_str());
613 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
615 "+++ Composite material \"%s\" [nor \"%s\"] not present! [delay resolution]",
617 ns.prepend(fracname).c_str());
621 ns.context()->unresolvedMaterials[nam].emplace_back(
626 TGeoMedium* medium = mgr.GetMedium(matname);
627 if (
nullptr == medium) {
629 medium =
new TGeoMedium(matname, unique_mat_id,
mix);
630 medium->SetTitle(
"material");
631 medium->SetUniqueID(unique_mat_id);
638 void Converter<DDLRotation>::operator()(xml_h element)
const {
641 xml_dim_t xrot(element);
642 string nam = xrot.nameStr();
644 double phiX = xrot.hasAttr(
DD_CMU(phiX)) ? ns.attr<
double>(xrot,
DD_CMU(phiX)) : 0e0;
646 double phiY = xrot.hasAttr(
DD_CMU(phiY)) ? ns.attr<
double>(xrot,
DD_CMU(phiY)) : 0e0;
648 double phiZ = xrot.hasAttr(
DD_CMU(phiZ)) ? ns.attr<
double>(xrot,
DD_CMU(phiZ)) : 0e0;
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(),
666 ns.addRotation(nam,
rot);
671 void Converter<DDLReflectionRotation>::operator()(xml_h element)
const {
674 xml_dim_t xrot(element);
675 string name = xrot.nameStr();
677 double phiX = xrot.hasAttr(
DD_CMU(phiX)) ? ns.attr<
double>(xrot,
DD_CMU(phiX)) : 0e0;
679 double phiY = xrot.hasAttr(
DD_CMU(phiY)) ? ns.attr<
double>(xrot,
DD_CMU(phiY)) : 0e0;
681 double phiZ = xrot.hasAttr(
DD_CMU(phiZ)) ? ns.attr<
double>(xrot,
DD_CMU(phiZ)) : 0e0;
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(),
704 void Converter<DDLRotationSequence>::operator()(xml_h element)
const {
707 xml_dim_t xrot(element);
708 string nam = xrot.nameStr();
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));
720 "+ Adding rotation to: %-29s: (axis/angle)[rad] Axis: %s Angle: %6.3f",
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(),
750 ns.addRotation(nam,
rot);
755 void Converter<DDLRotationByAxis>::operator()(xml_h element)
const {
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));
771 "+++ Adding rotation: %-32s: (axis/angle)[rad] Axis: %s Angle: %6.3f",
772 ns.prepend(nam).c_str(),
778 ns.addRotation(nam,
rot);
784 void Converter<DDLLogicalPart>::operator()(xml_h element)
const {
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);
797 ns.addVolume(
Volume(volName, solid, material));
801 printout(ns.context()->debug_volumes ? ALWAYS :
DEBUG,
803 "+++ %s Volume: %-24s [%s] Shape: %-32s [%s] Material: %-40s [%s]",
806 volume.isValid() ?
"VALID" :
"INVALID",
808 solid.isValid() ?
"VALID" :
"INVALID",
810 material.isValid() ?
"VALID" :
"INVALID");
817 void Converter<DDLTransform3D>::operator()(xml_h element)
const {
819 Transform3D* tr = _option<Transform3D>();
820 xml_dim_t
e(element);
823 xml_dim_t refRotation =
e.child(
DD_CMU(rRotation),
false);
824 xml_dim_t refReflectionRotation =
e.child(
DD_CMU(rReflectionRotation),
false);
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));
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);
846 *tr = Transform3D(
rot,
pos);
851 void Converter<DDLPosPart>::operator()(xml_h element)
const {
853 xml_dim_t
e(element);
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)));
862 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
864 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] copy:%d",
867 parent.isValid() ?
"VALID" :
"INVALID",
869 child.isValid() ?
"VALID" :
"INVALID",
875 parentName = ns.prepend(parentName);
876 parent = ns.volume(parentName);
879 childName = ns.prepend(childName);
880 child = ns.volume(childName,
false);
884 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
886 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] copy:%d",
889 parent.isValid() ?
"VALID" :
"INVALID",
891 child.isValid() ?
"VALID" :
"INVALID",
897 if (
child.isValid()) {
905 except(
"dd4hep",
"Volume: Attempt to assign daughters to an invalid physical parent volume.");
908 except(
"dd4hep",
"Volume: Attempt to assign an invalid physical daughter volume.");
910 TGeoShape* shape =
child->GetShape();
913 TGeoShapeAssembly* as = (TGeoShapeAssembly*)shape;
917 as->NeedsBBoxRecompute();
922 TString nam_id = TString::Format(
"%s_%d",
child->GetName(),
copy);
923 n = static_cast<TGeoNode*>(
parent->GetNode(nam_id));
925 printout(
ERROR,
"PlacedVolume",
"++ Attempt to add already exiting node %s", (
const char*)nam_id);
929 Translation3D trans(
transform.Translation());
931 trans.GetComponents(
x,
y,
z);
935 n = static_cast<TGeoNode*>(
parent->GetNode(nam_id));
936 n->TGeoNode::SetUserExtension(
new PlacedVolume::Object());
942 "+++ Placement FAILED! Parent:%s Child:%s Valid:%s",
945 yes_no(
child.isValid()));
951 void Converter<PartSelector>::operator()(xml_h element)
const {
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));
962 printout(ns.context()->debug_specpars ? ALWAYS :
DEBUG,
964 "+++ PartSelector for %s path: %s",
970 size_t pos = std::string::npos;
971 if ((
pos =
path.find(
"//.*:")) != std::string::npos) {
974 registry.specpars[specParName].paths.emplace_back(
std::move(
path));
979 void Converter<Parameter>::operator()(xml_h element)
const {
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();
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;
993 string type = eval ?
"number" :
"string";
997 printout(ns.context()->debug_specpars ? ALWAYS :
DEBUG,
999 "+++ Parameter for %s: %s value %s is a %s",
1000 specParName.c_str(),
1008 if (
idx == string::npos &&
type ==
"number") {
1009 registry.specpars[specParName].numpars[
name].emplace_back(dd4hep::_toDouble(
value));
1012 if (
idx == string::npos ||
type ==
"string") {
1017 while (
idx != string::npos) {
1021 if (idp == string::npos || idp > idq)
1023 else if (idp != string::npos && idp < idq)
1031 for (
idx =
v.find(
'[', 0);
idx != string::npos;
idx =
v.find(
'[',
idx + 1)) {
1032 idq =
v.find(
']',
idx + 1);
1034 auto r = ns.context()->description.constants().find(
rep);
1035 if (
r != ns.context()->description.constants().end()) {
1036 rep =
"(" +
r->second->type +
")";
1040 registry.specpars[specParName].numpars[
name].emplace_back(dd4hep::_toDouble(
value));
1043 template <
typename TYPE>
1046 xml_dim_t
e(element);
1047 string nam =
e.nameStr();
1048 string solidName[2];
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)));
1058 solidName[0] =
e.attr<
string>(
DD_CMU(firstSolid));
1059 if ((solids[0] = ns.
solid(
e.attr<
string>(
DD_CMU(firstSolid)))).isValid())
1061 solidName[1] =
e.attr<
string>(
DD_CMU(secondSolid));
1062 if ((solids[1] = ns.
solid(
e.attr<
string>(
DD_CMU(secondSolid)))).isValid())
1066 except(
"DD4CMS",
"+++ Failed to create boolean solid %s. Found only %d parts.", nam.c_str(), cnt);
1073 "+++ BooleanSolid: %s Left: %-32s Right: %-32s",
1075 ((solids[0].ptr() ==
nullptr) ? solidName[0].c_str() : solids[0]->GetName()),
1076 ((solids[1].ptr() ==
nullptr) ? solidName[1].c_str() : solids[1]->GetName()));
1080 if (solids[0].isValid() && solids[1].isValid()) {
1082 Converter<DDLTransform3D>(context->
description, context, &trafo)(element);
1083 boolean =
TYPE(solids[0], solids[1], trafo);
1087 Converter<DDLTransform3D>(context->
description, context, &trafo)(element);
1091 if (!
boolean.isValid()) {
1100 void Converter<DDLUnionSolid>::operator()(xml_h element)
const {
1101 convert_boolean<UnionSolid>(_param<cms::DDParsingContext>(), element);
1106 void Converter<DDLSubtractionSolid>::operator()(xml_h element)
const {
1107 convert_boolean<SubtractionSolid>(_param<cms::DDParsingContext>(), element);
1112 void Converter<DDLIntersectionSolid>::operator()(xml_h element)
const {
1113 convert_boolean<IntersectionSolid>(_param<cms::DDParsingContext>(), element);
1118 void Converter<DDLPolycone>::operator()(xml_h element)
const {
1120 xml_dim_t
e(element);
1121 string nam =
e.nameStr();
1122 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1124 vector<double>
z, rmin, rmax,
r;
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)));
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)));
1139 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1141 "+ Polycone: startPhi=%10.3f [rad] deltaPhi=%10.3f [rad] %4ld z-planes",
1148 ns.addSolid(nam, Polycone(startPhi,
deltaPhi, rmin, rmax,
z));
1152 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1154 "+ Polycone: startPhi=%10.3f [rad] deltaPhi=%10.3f [rad] %4ld z-planes and %4ld radii",
1162 ns.addSolid(nam, Polycone(startPhi,
deltaPhi,
r,
z));
1168 void Converter<DDLExtrudedPolygon>::operator()(xml_h element)
const {
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;
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));
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)));
1187 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1189 "+ ExtrudedPolygon: %4ld points %4ld zxy sections",
1195 ns.addSolid(nam,
ExtrudedPolygon(pt_x, pt_y, sec_z, sec_x, sec_y, sec_scale));
1200 void Converter<DDLPolyhedra>::operator()(xml_h element)
const {
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));
1207 vector<double>
z, rmin, rmax;
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)));
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)));
1222 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1224 "+ Polyhedra:startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] %4d sides %4ld z-planes",
1237 void Converter<DDLSphere>::operator()(xml_h element)
const {
1239 xml_dim_t
e(element);
1240 string nam =
e.nameStr();
1243 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1245 double startTheta = ns.attr<
double>(
e,
DD_CMU(startTheta));
1246 double deltaTheta = ns.attr<
double>(
e,
DD_CMU(deltaTheta));
1250 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
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]",
1263 ns.addSolid(nam, Sphere(rinner, router, startTheta, deltaTheta, startPhi,
deltaPhi));
1268 void Converter<DDLTorus>::operator()(xml_h element)
const {
1270 xml_dim_t
e(element);
1271 string nam =
e.nameStr();
1272 double r = ns.attr<
double>(
e,
DD_CMU(torusRadius));
1275 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1280 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
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]",
1292 ns.addSolid(nam, Torus(
r, rinner, router, startPhi,
deltaPhi));
1297 void Converter<DDLPseudoTrap>::operator()(xml_h element)
const {
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));
1311 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1313 "+ Pseudotrap: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2=%.3f dy2=%.3f radius:%.3f atMinusZ:%s",
1324 ns.addSolid(nam, PseudoTrap(dx1, dx2, dy1, dy2,
dz,
r, atMinusZ));
1329 void Converter<DDLTrapezoid>::operator()(xml_h element)
const {
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);
1347 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1349 "+ Trapezoid: dz=%10.3f [cm] alp1:%.3f bl1=%.3f tl1=%.3f alp2=%.3f bl2=%.3f tl2=%.3f h2=%.3f phi=%.3f "
1365 ns.addSolid(nam, Trap(
dz,
theta,
phi, h1, bl1, tl1, alp1, h2, bl2, tl2, alp2));
1370 void Converter<DDLTrd1>::operator()(xml_h element)
const {
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);
1382 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1384 "+ Trd1: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1393 ns.addSolid(nam, Trd1(dx1, dx2, dy1,
dz));
1397 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1399 "+ Trd1(which is actually Trd2): dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1408 ns.addSolid(nam, Trd2(dx1, dx2, dy1, dy2,
dz));
1414 void Converter<DDLTrd2>::operator()(xml_h element)
const {
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);
1426 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1428 "+ Trd1: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1437 ns.addSolid(nam, Trd2(dx1, dx2, dy1, dy2,
dz));
1442 void Converter<DDLTubs>::operator()(xml_h element)
const {
1444 xml_dim_t
e(element);
1445 string nam =
e.nameStr();
1449 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi), 0.0);
1454 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1456 "+ Tubs: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
1457 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]",
1466 ns.addSolid(nam, Tube(rmin, rmax,
dz, startPhi, startPhi +
deltaPhi));
1471 void Converter<DDLCutTubs>::operator()(xml_h element)
const {
1473 xml_dim_t
e(element);
1474 string nam =
e.nameStr();
1478 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
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));
1489 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1491 "+ CutTube: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
1492 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]...",
1501 ns.addSolid(nam, CutTube(rmin, rmax,
dz, startPhi, startPhi +
deltaPhi, lx, ly, lz, tx, ty, tz));
1506 void Converter<DDLTruncTubs>::operator()(xml_h element)
const {
1508 xml_dim_t
e(element);
1509 string nam =
e.nameStr();
1510 double zhalf = ns.attr<
double>(
e,
DD_CMU(zHalf));
1513 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
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));
1521 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
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",
1536 ns.addSolid(nam, TruncatedTube(zhalf, rmin, rmax, startPhi,
deltaPhi, cutAtStart, cutAtDelta, cutInside));
1541 void Converter<DDLEllipticalTube>::operator()(xml_h element)
const {
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));
1551 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1553 "+ EllipticalTube xSemiAxis=%8.3f [cm] ySemiAxis=%8.3f [cm] zHeight=%8.3f [cm]",
1560 ns.addSolid(nam, EllipticalTube(
dx,
dy,
dz));
1565 void Converter<DDLCone>::operator()(xml_h element)
const {
1567 xml_dim_t
e(element);
1568 string nam =
e.nameStr();
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));
1580 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
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]",
1596 ns.addSolid(nam, ConeSegment(
dz, rmin1, rmax1, rmin2, rmax2, startPhi, phi2));
1601 void Converter<DDLShapeless>::operator()(xml_h element)
const {
1603 xml_dim_t
e(element);
1604 string nam =
e.nameStr();
1608 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1610 "+ Shapeless: THIS ONE CAN ONLY BE USED AT THE VOLUME LEVEL -> Assembly%s",
1615 ns.addSolid(nam, Box(1, 1, 1));
1620 void Converter<DDLBox>::operator()(xml_h element)
const {
1622 xml_dim_t
e(element);
1623 string nam =
e.nameStr();
1630 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1632 "+ Box: dx=%10.3f [cm] dy=%10.3f [cm] dz=%10.3f [cm]",
1639 ns.addSolid(nam, Box(
dx,
dy,
dz));
1644 void Converter<include_load>::operator()(xml_h element)
const {
1645 string fname = element.attr<
string>(_U(ref));
1648 doc = xml::DocumentHandler().load(
fp.fullPath());
1652 printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS :
DEBUG,
1654 "+++ Processing the CMS detector description %s",
1659 _option<DDRegistry>()->includes.emplace_back(
doc);
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);
1670 printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS :
DEBUG,
1672 "+++ Finished processing %s",
1679 void Converter<include_constants>::operator()(xml_h element)
const {
1692 const std::map<std::string, DDAxes> axesmap{{
"x",
DDAxes::x},
1702 void Converter<DDLDivision>::operator()(xml_h element)
const {
1704 xml_dim_t
e(element);
1705 string childName =
e.nameStr();
1707 childName = ns.prepend(childName);
1711 parentName = ns.prepend(parentName);
1712 string axis = ns.attr<
string>(
e,
DD_CMU(axis));
1718 int nReplicas =
e.hasAttr(
DD_CMU(nReplicas)) ? ns.attr<
int>(
e,
DD_CMU(nReplicas)) : 0;
1722 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1724 "+++ Start executing Division of %s along %s (%d) with offset %6.3f and %6.3f to produce %s....",
1736 const TGeoShape* shape =
parent.solid();
1737 TClass*
cl = shape->IsA();
1739 const TGeoTubeSeg* sh = (
const TGeoTubeSeg*)shape;
1742 int numCopies = (
int)((sh->GetPhi2() - sh->GetPhi1()) / widthInDeg);
1746 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1748 "+++ ...divide %s along %s (%d) with offset %6.3f deg and %6.3f deg to produce %d copies",
1758 Volume child =
parent.divide(childName, static_cast<int>(axesmap.at(axis)), numCopies, startInDeg, widthInDeg);
1760 ns.context()->volumes[childName] =
child;
1764 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1766 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] is multivolume [%s]",
1769 parent.isValid() ?
"VALID" :
"INVALID",
1771 child.isValid() ?
"VALID" :
"INVALID",
1772 child->IsVolumeMulti() ?
"YES" :
"NO");
1776 double dy = static_cast<const TGeoTrd1*>(shape)->GetDy();
1780 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1782 "+++ ...divide %s along %s (%d) with offset %6.3f cm and %6.3f cm to produce %d copies in %6.3f",
1795 ns.context()->volumes[childName] =
child;
1799 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1801 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] is multivolume [%s]",
1804 parent.isValid() ?
"VALID" :
"INVALID",
1806 child.isValid() ?
"VALID" :
"INVALID",
1807 child->IsVolumeMulti() ?
"YES" :
"NO");
1812 printout(
ERROR,
"DD4CMS",
"++ FAILED Division of a %s is not implemented yet!",
parent.solid().type());
1818 void Converter<DDLAlgorithm>::operator()(xml_h element)
const {
1820 xml_dim_t
e(element);
1821 string name =
e.nameStr();
1823 string type =
"DDCMS_" + ns.realName(
name);
1830 ns.context()->debug_algorithms ? ALWAYS :
DEBUG,
"DD4CMS",
"+++ Start executing algorithm %s....",
type.c_str());
1838 printout(ns.context()->debug_algorithms ? ALWAYS :
DEBUG,
1841 "+++ Executed algorithm: %08lX = %s",
1848 printout(
ERROR,
"DD4CMS",
"++ FAILED NOT ADDING SUBDETECTOR %08lX = %s",
ret,
name.c_str());
1851 template <
class InputIt,
class ForwardIt,
class BinOp>
1854 const auto pos = std::find_first_of(
first,
last, s_first, s_last);
1864 std::vector<string>
splitString(
const string&
str,
const string& delims =
",") {
1865 std::vector<string>
output;
1879 std::vector<double> splitNumeric(
const string&
str,
const string& delims =
",") {
1880 std::vector<double>
output;
1898 void Converter<DDLVector>::operator()(xml_h element)
const {
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());
1911 printout(ns.context()->debug_constants ? ALWAYS :
DEBUG,
1913 "+++ Vector<%s>: %s[%s]: %s",
1922 std::vector<double>
results = splitNumeric(
val);
1931 "++ Unresolved Vector<%s>: %s[%s]: %s. Try to resolve later. [%s]",
1946 void Converter<debug>::operator()(xml_h dbg)
const {
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;
1971 void Converter<DDRegistry>::operator()(xml_h )
const {
1973 DDRegistry*
res = _option<DDRegistry>();
1981 "+++ RESOLVING %ld unknown constants..... (out of %ld)",
1982 res->unresolvedConst.size(),
1983 res->originalConst.size());
1986 while (!
res->unresolvedConst.empty()) {
1987 for (
auto&
i :
res->unresolvedConst) {
1988 const string&
n =
i.first;
1990 string&
v =
i.second;
1992 for (
idx =
v.find(
'[', 0);
idx != string::npos;
idx =
v.find(
'[',
idx + 1)) {
1993 idq =
v.find(
']',
idx + 1);
1995 auto r =
res->originalConst.find(
rep);
1996 if (
r !=
res->originalConst.end()) {
1997 rep =
"(" + (*r).second +
")";
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,
"-");
2013 "+++ [%06ld] ---------- %-40s = %s",
2014 res->unresolvedConst.size() - 1,
2016 res->originalConst[
n].c_str());
2020 ns.addConstantNS(
n,
v,
"number");
2021 res->unresolvedConst.erase(
n);
2025 if (++
count > 10000)
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());
2033 res->unresolvedConst.clear();
2034 res->originalConst.clear();
2038 void Converter<print_xml_doc>::operator()(xml_h element)
const {
2039 string fname = xml::DocumentHandler::system_path(element);
2043 printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS :
DEBUG,
2045 "+++ Processing data from: %s",
2053 xml_elt_t dddef(element);
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;
2069 xml_coll_t(dddef, _U(
debug)).for_each(Converter<debug>(det, &context));
2074 printout(
INFO,
"DD4CMS",
"+++ Processing the CMS detector description %s",
fname.c_str());
2077 Converter<print_xml_doc> print_doc(det, &context);
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));
2087 xml_coll_t(dddef,
DD_CMU(IncludeSection)).for_each(
DD_CMU(Include), Converter<include_load>(det, &context, &
res));
2089 for (xml::Document
d :
res.includes) {
2091 Converter<include_constants>(det, &context, &
res)((
doc =
d).
root());
2094 Converter<DDRegistry>(det, &context, &
res)(dddef);
2100 "+++ RESOLVING %ld Vectors.....",
2105 std::vector<double>
result;
2106 for (
const auto&
i : it->second) {
2107 result.emplace_back(dd4hep::_toDouble(
i));
2109 registry->insert({it->first,
result});
2116 for (xml::Document
d :
res.includes) {
2118 xml_coll_t(
d.root(),
DD_CMU(MaterialSection)).for_each(Converter<MaterialSection>(det, &context));
2123 "+++ RESOLVING %ld unknown material constituents.....",
2130 auto const&
name = it->first;
2131 std::vector<bool>
valid;
2135 "+++ [%06ld] ---------- %s",
2140 for (
auto& mit : it->second) {
2143 "+++ component %-48s Fraction: %.6f",
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);
2156 if (
valid.size() == it->second.size())
2165 if (open_geometry) {
2169 for (xml::Document
d :
res.includes) {
2171 xml_coll_t(
d.root(),
DD_CMU(RotationSection)).for_each(Converter<RotationSection>(det, &context));
2173 for (xml::Document
d :
res.includes) {
2175 xml_coll_t(
d.root(),
DD_CMU(SolidSection)).for_each(Converter<SolidSection>(det, &context));
2177 for (xml::Document
d :
res.includes) {
2179 xml_coll_t(
d.root(),
DD_CMU(LogicalPartSection)).for_each(Converter<LogicalPartSection>(det, &context));
2181 for (xml::Document
d :
res.includes) {
2183 xml_coll_t(
d.root(),
DD_CMU(
Algorithm)).for_each(Converter<DDLAlgorithm>(det, &context));
2185 for (xml::Document
d :
res.includes) {
2187 xml_coll_t(
d.root(),
DD_CMU(PosPartSection)).for_each(Converter<PosPartSection>(det, &context));
2189 for (xml::Document
d :
res.includes) {
2191 xml_coll_t(
d.root(),
DD_CMU(SpecParSection)).for_each(Converter<SpecParSection>(det, &context));
2195 for (xml::Document
d :
res.includes)
2196 Converter<include_unload>(det, &context, &
res)(
d.root());
2198 print_doc((
doc = dddef.document()).
root());
2200 xml_coll_t(dddef,
DD_CMU(SolidSection)).for_each(Converter<SolidSection>(det, &context));
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);
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); },
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));
2234 printout(
ERROR,
"DD4CMS",
"Exception while processing xml source:%s",
doc.uri().c_str());
2235 printout(
ERROR,
"DD4CMS",
"----> %s",
e.what());
2240 if (close_geometry) {
2241 Volume wv = det.worldVolume();
2243 if (geomv.isValid())
2244 wv.placeVolume(geomv, 1);
2245 Volume mfv = ns.
volume(
"cmsMagneticField:MAGF",
false);
2247 wv.placeVolume(mfv, 1);
2248 Volume mfv1 = ns.
volume(
"MagneticFieldVolumes:MAGF",
false);
2250 wv.placeVolume(mfv1, 1);
2253 det.manager().CloseGeometry();
2257 printout(
INFO,
"DDDefinition",
"+++ Finished processing %s",
fname.c_str());
2260 except(
"DDDefinition",
"+++ FAILED to process unknown DOM tree [Invalid Handle]");