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;
96 class DDLIntersectionSolid;
97 class DDLSubtractionSolid;
102 class SpecParSection;
116 TGeoTranslation
t(iTrans.x(), iTrans.y(), iTrans.z());
118 return new TGeoCombiTrans(
t,
r);
123 void Converter<debug>::operator()(xml_h element)
const;
125 void Converter<print_xml_doc>::operator()(xml_h element)
const;
129 void Converter<ConstantsSection>::operator()(xml_h element)
const;
131 void Converter<DDLConstant>::operator()(xml_h element)
const;
133 void Converter<DDRegistry>::operator()(xml_h element)
const;
137 void Converter<MaterialSection>::operator()(xml_h element)
const;
139 void Converter<DDLElementaryMaterial>::operator()(xml_h element)
const;
141 void Converter<DDLCompositeMaterial>::operator()(xml_h element)
const;
145 void Converter<RotationSection>::operator()(xml_h element)
const;
148 void Converter<DDLRotation>::operator()(xml_h element)
const;
151 void Converter<DDLReflectionRotation>::operator()(xml_h element)
const;
154 void Converter<DDLRotationSequence>::operator()(xml_h element)
const;
157 void Converter<DDLRotationByAxis>::operator()(xml_h element)
const;
159 void Converter<DDLTransform3D>::operator()(xml_h element)
const;
163 void Converter<LogicalPartSection>::operator()(xml_h element)
const;
165 void Converter<DDLLogicalPart>::operator()(xml_h element)
const;
169 void Converter<PosPartSection>::operator()(xml_h element)
const;
172 void Converter<DDLPosPart>::operator()(xml_h element)
const;
175 void Converter<DDLDivision>::operator()(xml_h element)
const;
179 void Converter<SpecParSection>::operator()(xml_h element)
const;
181 void Converter<DDLSpecPar>::operator()(xml_h element)
const;
183 void Converter<PartSelector>::operator()(xml_h element)
const;
185 void Converter<Parameter>::operator()(xml_h element)
const;
189 void Converter<SolidSection>::operator()(xml_h element)
const;
192 void Converter<DDLUnionSolid>::operator()(xml_h element)
const;
195 void Converter<DDLSubtractionSolid>::operator()(xml_h element)
const;
198 void Converter<DDLIntersectionSolid>::operator()(xml_h element)
const;
201 void Converter<DDLPseudoTrap>::operator()(xml_h element)
const;
204 void Converter<DDLExtrudedPolygon>::operator()(xml_h element)
const;
207 void Converter<DDLShapeless>::operator()(xml_h element)
const;
210 void Converter<DDLAssembly>::operator()(xml_h element)
const;
213 void Converter<DDLTrapezoid>::operator()(xml_h element)
const;
216 void Converter<DDLPolycone>::operator()(xml_h element)
const;
219 void Converter<DDLPolyhedra>::operator()(xml_h element)
const;
222 void Converter<DDLEllipticalTube>::operator()(xml_h element)
const;
225 void Converter<DDLTorus>::operator()(xml_h element)
const;
228 void Converter<DDLTubs>::operator()(xml_h element)
const;
231 void Converter<DDLCutTubs>::operator()(xml_h element)
const;
234 void Converter<DDLTruncTubs>::operator()(xml_h element)
const;
237 void Converter<DDLSphere>::operator()(xml_h element)
const;
240 void Converter<DDLTrd1>::operator()(xml_h element)
const;
243 void Converter<DDLTrd2>::operator()(xml_h element)
const;
246 void Converter<DDLCone>::operator()(xml_h element)
const;
249 void Converter<DDLBox>::operator()(xml_h element)
const;
252 void Converter<DDLAlgorithm>::operator()(xml_h element)
const;
255 void Converter<DDLVector>::operator()(xml_h element)
const;
259 void Converter<include_load>::operator()(xml_h element)
const;
262 void Converter<include_unload>::operator()(xml_h element)
const;
265 void Converter<include_constants>::operator()(xml_h element)
const;
270 void Converter<ConstantsSection>::operator()(xml_h element)
const {
279 void Converter<MaterialSection>::operator()(xml_h element)
const {
281 xml_coll_t(element,
DD_CMU(ElementaryMaterial))
283 xml_coll_t(element,
DD_CMU(CompositeMaterial))
288 void Converter<RotationSection>::operator()(xml_h element)
const {
291 xml_coll_t(element,
DD_CMU(ReflectionRotation))
293 xml_coll_t(element,
DD_CMU(RotationSequence))
295 xml_coll_t(element,
DD_CMU(RotationByAxis))
300 void Converter<PosPartSection>::operator()(xml_h element)
const {
308 void Converter<SpecParSection>::operator()(xml_h element)
const {
314 void Converter<DDLSpecPar>::operator()(xml_h element)
const {
322 void Converter<LogicalPartSection>::operator()(xml_h element)
const {
329 void Converter<SolidSection>::operator()(xml_h element)
const {
331 for (xml_coll_t solid(element, _U(star)); solid; ++solid) {
333 switch (
hash(solid.tag())) {
337 case hash(
"Polycone"):
340 case hash(
"Polyhedra"):
346 case hash(
"CutTubs"):
349 case hash(
"TruncTubs"):
367 case hash(
"EllipticalTube"):
373 case hash(
"PseudoTrap"):
376 case hash(
"ExtrudedPolygon"):
379 case hash(
"Trapezoid"):
382 case hash(
"UnionSolid"):
385 case hash(
"SubtractionSolid"):
388 case hash(
"IntersectionSolid"):
391 case hash(
"ShapelessSolid"):
394 case hash(
"Assembly"):
398 throw std::runtime_error(
"Request to process unknown shape '" + xml_dim_t(solid).nameStr() +
"' [" +
407 void Converter<DDLConstant>::operator()(xml_h element)
const {
409 DDRegistry*
res = _option<DDRegistry>();
410 xml_dim_t constant = element;
411 xml_dim_t par = constant.parent();
412 bool eval = par.hasAttr(_U(eval)) ? par.attr<
bool>(_U(eval)) :
true;
413 string val = constant.valueStr();
414 string nam = constant.nameStr();
415 string real = ns.prepend(nam);
416 string typ = eval ?
"number" :
"string";
417 size_t idx =
val.find(
'[');
419 if (constant.hasAttr(_U(
type)))
420 typ = constant.typeStr();
422 if (
idx == string::npos || typ ==
"string") {
424 ns.addConstant(nam,
val, typ);
425 res->originalConst[real] =
val;
431 "++ Unresolved constant: %s = %s [%s]. Try to resolve later. [%s]",
441 while (
idx != string::npos) {
443 size_t idp =
val.find(
':',
idx);
444 size_t idq =
val.find(
']',
idx);
445 if (idp == string::npos || idp > idq)
446 val.insert(
idx, ns.name());
447 else if (idp != string::npos && idp < idq)
455 ns.context()->debug_constants ? ALWAYS :
DEBUG,
"Constant",
"Unresolved: %s -> %s", real.c_str(),
val.c_str());
459 res->originalConst[real] =
val;
460 res->unresolvedConst[real] =
val;
465 void Converter<DDLElementaryMaterial>::operator()(xml_h element)
const {
467 xml_dim_t xmat(element);
468 string nam = ns.prepend(xmat.nameStr());
470 TGeoMaterial* mat = mgr.GetMaterial(nam.c_str());
471 if (
nullptr == mat) {
472 const char* matname = nam.c_str();
474 int atomicNumber = xmat.attr<
int>(
DD_CMU(atomicNumber));
475 double atomicWeight = xmat.attr<
double>(
DD_CMU(atomicWeight)) / (
dd4hep::g / dd4hep::mole);
476 TGeoElementTable* tab = mgr.GetElementTable();
477 int nElem = tab->GetNelements();
481 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
"DD4CMS",
"+++ Element table size = %d", nElem);
486 tab->TGeoElementTable::~TGeoElementTable();
487 new (tab) TGeoElementTable();
488 tab->BuildDefaultElements();
490 TGeoMixture*
mix =
new TGeoMixture(nam.c_str(), 1,
density);
491 TGeoElement* elt = tab->FindElement(xmat.nameStr().c_str());
495 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
497 "+++ Searching for material %-48s elt_ptr = %ld",
498 xmat.nameStr().c_str(),
501 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
503 "+++ Converting material %-48s Atomic weight %8.3f [g/mol], Atomic number %u, Density: %8.3f [g/cm3] "
504 "ROOT: %8.3f [g/cm3]",
505 (
'"' + nam +
'"').c_str(),
513 bool newMatDef =
false;
520 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
522 " ROOT definition of %-50s Atomic weight %g, Atomic number %u, Number of nucleons %u",
527 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
529 "+++ Compared to XML values: Atomic weight %g, Atomic number %u",
534 static constexpr
double const weightTolerance = 1.0e-6;
535 if (atomicNumber != elt->Z() ||
536 (
std::abs(atomicWeight - elt->A()) > (weightTolerance * (atomicWeight + elt->A()))))
540 if (!elt || newMatDef) {
544 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
546 "+++ Converter<ElementaryMaterial> Different definition of a default element with name:%s [CREATE NEW "
555 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
557 "+++ Converter<ElementaryMaterial> No default element present with name:%s [CREATE NEW MATERIAL]",
562 elt =
new TGeoElement(xmat.nameStr().c_str(),
"CMS element", atomicNumber, atomicWeight);
565 mix->AddElement(elt, 1.0);
566 mix->SetTemperature(ns.context()->description.stdConditions().temperature);
567 mix->SetPressure(ns.context()->description.stdConditions().pressure);
570 TGeoMedium* medium = mgr.GetMedium(matname);
571 if (
nullptr == medium) {
573 medium =
new TGeoMedium(matname, unique_mat_id,
mix);
574 medium->SetTitle(
"material");
575 medium->SetUniqueID(unique_mat_id);
582 void Converter<DDLCompositeMaterial>::operator()(xml_h element)
const {
584 xml_dim_t xmat(element);
585 string nam = ns.prepend(xmat.nameStr());
588 TGeoMaterial* mat = mgr.GetMaterial(nam.c_str());
589 if (
nullptr == mat) {
590 const char* matname = nam.c_str();
592 xml_coll_t composites(xmat,
DD_CMU(MaterialFraction));
593 TGeoMixture*
mix =
new TGeoMixture(nam.c_str(), composites.size(),
density);
597 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
599 "++ Converting material %-48s Density: %8.3f [g/cm3] ROOT: %8.3f [g/cm3]",
600 (
'"' + nam +
'"').c_str(),
606 if (ns.context()->makePayload) {
607 ns.context()->compMaterialsVec.emplace_back(std::make_pair(nam,
density));
609 for (composites.reset(); composites; ++composites) {
610 xml_dim_t xfrac(composites);
611 xml_dim_t xfrac_mat(xfrac.child(
DD_CMU(rMaterial)));
613 string fracname = ns.realName(xfrac_mat.nameStr());
615 if (ns.context()->makePayload) {
616 ns.context()->compMaterialsRefs[nam].emplace_back(
619 TGeoMaterial* frac_mat = mgr.GetMaterial(fracname.c_str());
620 if (frac_mat ==
nullptr)
621 frac_mat = mgr.GetMaterial(ns.prepend(fracname).c_str());
629 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
631 "+++ Composite material \"%s\" [nor \"%s\"] not present! [delay resolution]",
633 ns.prepend(fracname).c_str());
637 ns.context()->unresolvedMaterials[nam].emplace_back(
640 mix->SetTemperature(ns.context()->description.stdConditions().temperature);
641 mix->SetPressure(ns.context()->description.stdConditions().pressure);
644 TGeoMedium* medium = mgr.GetMedium(matname);
645 if (
nullptr == medium) {
647 medium =
new TGeoMedium(matname, unique_mat_id,
mix);
648 medium->SetTitle(
"material");
649 medium->SetUniqueID(unique_mat_id);
656 void Converter<DDLRotation>::operator()(xml_h element)
const {
659 xml_dim_t xrot(element);
660 string nam = xrot.nameStr();
662 double phiX = xrot.hasAttr(
DD_CMU(phiX)) ? ns.attr<
double>(xrot,
DD_CMU(phiX)) : 0e0;
664 double phiY = xrot.hasAttr(
DD_CMU(phiY)) ? ns.attr<
double>(xrot,
DD_CMU(phiY)) : 0e0;
666 double phiZ = xrot.hasAttr(
DD_CMU(phiZ)) ? ns.attr<
double>(xrot,
DD_CMU(phiZ)) : 0e0;
673 "+++ Adding rotation: %-32s: (theta/phi)[rad] X: %6.3f %6.3f Y: %6.3f %6.3f Z: %6.3f %6.3f",
674 ns.prepend(nam).c_str(),
684 ns.addRotation(nam,
rot);
689 void Converter<DDLReflectionRotation>::operator()(xml_h element)
const {
692 xml_dim_t xrot(element);
693 string name = xrot.nameStr();
695 double phiX = xrot.hasAttr(
DD_CMU(phiX)) ? ns.attr<
double>(xrot,
DD_CMU(phiX)) : 0e0;
697 double phiY = xrot.hasAttr(
DD_CMU(phiY)) ? ns.attr<
double>(xrot,
DD_CMU(phiY)) : 0e0;
699 double phiZ = xrot.hasAttr(
DD_CMU(phiZ)) ? ns.attr<
double>(xrot,
DD_CMU(phiZ)) : 0e0;
705 "+++ Adding reflection rotation: %-32s: (theta/phi)[rad] X: %6.3f %6.3f Y: %6.3f %6.3f Z: %6.3f %6.3f",
706 ns.prepend(
name).c_str(),
722 void Converter<DDLRotationSequence>::operator()(xml_h element)
const {
725 xml_dim_t xrot(element);
726 string nam = xrot.nameStr();
728 xml_coll_t rotations(xrot,
DD_CMU(RotationByAxis));
729 for (rotations.reset(); rotations; ++rotations) {
730 string axis = ns.attr<
string>(rotations,
DD_CMU(axis));
731 double angle = ns.attr<
double>(rotations, _U(
angle));
738 "+ Adding rotation to: %-29s: (axis/angle)[rad] Axis: %s Angle: %6.3f",
754 "+++ Adding rotation sequence: %-23s: %6.3f %6.3f %6.3f, %6.3f %6.3f %6.3f, %6.3f %6.3f %6.3f",
755 ns.prepend(nam).c_str(),
768 ns.addRotation(nam,
rot);
773 void Converter<DDLRotationByAxis>::operator()(xml_h element)
const {
776 xml_dim_t xrot(element);
777 xml_dim_t par(xrot.parent());
778 if (xrot.hasAttr(_U(
name))) {
779 string nam = xrot.nameStr();
780 string axis = ns.attr<
string>(xrot,
DD_CMU(axis));
781 double angle = ns.attr<
double>(xrot, _U(
angle));
789 "+++ Adding rotation: %-32s: (axis/angle)[rad] Axis: %s Angle: %6.3f",
790 ns.prepend(nam).c_str(),
796 ns.addRotation(nam,
rot);
802 void Converter<DDLLogicalPart>::operator()(xml_h element)
const {
804 xml_dim_t
e(element);
805 string sol =
e.child(
DD_CMU(rSolid)).attr<
string>(_U(
name));
806 string mat =
e.child(
DD_CMU(rMaterial)).attr<
string>(_U(
name));
807 string volName = ns.prepend(
e.attr<
string>(_U(
name)));
808 Solid solid = ns.solid(sol);
809 Material material = ns.material(mat);
810 if (ns.context()->assemblySolids.count(sol) == 1) {
814 ns.addAssembly(volName,
false);
822 ns.addVolume(
Volume(volName, solid, material));
826 printout(ns.context()->debug_volumes ? ALWAYS :
DEBUG,
828 "+++ %s Volume: %-24s [%s] Shape: %-32s [%s] Material: %-40s [%s]",
831 volume.isValid() ?
"VALID" :
"INVALID",
833 solid.isValid() ?
"VALID" :
"INVALID",
835 material.isValid() ?
"VALID" :
"INVALID");
842 void Converter<DDLTransform3D>::operator()(xml_h element)
const {
844 Transform3D* tr = _option<Transform3D>();
845 xml_dim_t
e(element);
848 xml_dim_t refRotation =
e.child(
DD_CMU(rRotation),
false);
849 xml_dim_t refReflectionRotation =
e.child(
DD_CMU(rReflectionRotation),
false);
853 if (translation.ptr()) {
854 double x = ns.attr<
double>(translation, _U(
x));
855 double y = ns.attr<
double>(translation, _U(
y));
856 double z = ns.attr<
double>(translation, _U(
z));
863 rot = RotationZYX(
z,
y,
x);
864 }
else if (refRotation.ptr()) {
865 string rotName = ns.prepend(refRotation.nameStr());
867 }
else if (refReflectionRotation.ptr()) {
868 string rotName = ns.prepend(refReflectionRotation.nameStr());
871 *tr = Transform3D(
rot,
pos);
875 const string& parentName,
877 const string& childName,
885 "+++ Parent vol: %-24s Child: %-32s, copy:%d",
892 TGeoShape* shape = (*childPtr)->GetShape();
895 TGeoShapeAssembly* as = (TGeoShapeAssembly*)shape;
899 as->NeedsBBoxRecompute();
904 TString nam_id = TString::Format(
"%s_%d", (*childPtr)->GetName(),
copy);
905 n = static_cast<TGeoNode*>((*parentPtr)->GetNode(nam_id));
907 printout(
ERROR,
"PlacedVolume",
"++ Attempt to add already existing node %s", (
const char*)nam_id);
912 if ((*childPtr)->IsAssembly()) {
919 printout(
ERROR,
"DD4CMS",
"+++ Placement FAILED! Parent:%s Child:%s", parentName.c_str(), childName.c_str());
925 void Converter<DDLPosPart>::operator()(xml_h element)
const {
927 xml_dim_t
e(element);
929 string parentName = ns.prepend(ns.attr<
string>(
e.child(
DD_CMU(rParent)), _U(
name)));
930 string childName = ns.prepend(ns.attr<
string>(
e.child(
DD_CMU(rChild)), _U(
name)));
936 Assembly parAsmb = ns.assembly(parentName,
false);
937 Assembly childAsmb = ns.assembly(childName,
false);
941 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
943 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] copy:%d",
946 parent.isValid() ?
"VALID" :
"INVALID",
948 child.isValid() ?
"VALID" :
"INVALID",
953 if (!
parent.isValid() && !parAsmb.isValid() && strchr(parentName.c_str(),
NAMESPACE_SEP) ==
nullptr) {
954 parentName = ns.prepend(parentName);
955 parAsmb = ns.assembly(parentName,
false);
956 if (!parAsmb.isValid())
957 parent = ns.volume(parentName);
960 if (!
child.isValid() && !childAsmb.isValid() && strchr(childName.c_str(),
NAMESPACE_SEP) ==
nullptr) {
961 childName = ns.prepend(childName);
962 child = ns.volume(childName,
false);
963 childAsmb = ns.assembly(childName,
false);
965 if (parAsmb.isValid() || childAsmb.isValid()) {
966 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
968 "***** Placing assembly parent %s, child %s",
971 Volume* parentPtr = parAsmb.isValid() ? &parAsmb : &
parent;
972 Volume* childPtr = childAsmb.isValid() ? &childAsmb : &
child;
979 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
981 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] copy:%d",
984 parent.isValid() ?
"VALID" :
"INVALID",
986 child.isValid() ?
"VALID" :
"INVALID",
992 if (
child.isValid()) {
997 except(
"dd4hep",
"Volume: Attempt to assign daughters to an invalid physical parent volume.");
1000 except(
"dd4hep",
"Volume: Attempt to assign an invalid physical daughter volume.");
1002 TGeoShape* shape =
child->GetShape();
1005 TGeoShapeAssembly* as = (TGeoShapeAssembly*)shape;
1009 as->NeedsBBoxRecompute();
1014 TString nam_id = TString::Format(
"%s_%d",
child->GetName(),
copy);
1015 n = static_cast<TGeoNode*>(
parent->GetNode(nam_id));
1017 printout(
ERROR,
"PlacedVolume",
"++ Attempt to add already existing node %s", (
const char*)nam_id);
1021 Translation3D trans(
transform.Translation());
1023 trans.GetComponents(
x,
y,
z);
1027 n = static_cast<TGeoNode*>(
parent->GetNode(nam_id));
1028 n->TGeoNode::SetUserExtension(
new PlacedVolume::Object());
1031 if (!
pv.isValid()) {
1034 "+++ Placement FAILED! Parent:%s Child:%s Valid:%s",
1037 yes_no(
child.isValid()));
1043 void Converter<PartSelector>::operator()(xml_h element)
const {
1046 dd4hep::SpecParRegistry& registry = *
context->description.extension<dd4hep::SpecParRegistry>();
1047 xml_dim_t
e(element);
1048 xml_dim_t specPar =
e.parent();
1049 string specParName = specPar.attr<
string>(_U(
name));
1054 printout(ns.context()->debug_specpars ? ALWAYS :
DEBUG,
1056 "+++ PartSelector for %s path: %s",
1057 specParName.c_str(),
1062 size_t pos = std::string::npos;
1063 if ((
pos =
path.find(
"//.*:")) != std::string::npos) {
1066 registry.specpars[specParName].paths.emplace_back(
std::move(
path));
1071 void Converter<Parameter>::operator()(xml_h element)
const {
1074 dd4hep::SpecParRegistry& registry = *
context->description.extension<dd4hep::SpecParRegistry>();
1075 xml_dim_t
e(element);
1076 xml_dim_t specPar =
e.parent();
1077 xml_dim_t specParSect = specPar.parent();
1078 string specParName = specPar.attr<
string>(_U(
name));
1079 string name =
e.nameStr();
1081 bool eval = specParSect.hasAttr(_U(eval)) ? specParSect.attr<
bool>(_U(eval)) :
false;
1082 eval = specPar.hasAttr(_U(eval)) ? specPar.attr<
bool>(_U(eval)) : eval;
1083 eval =
e.hasAttr(_U(eval)) ?
e.attr<
bool>(_U(eval)) : eval;
1085 string type = eval ?
"number" :
"string";
1089 printout(ns.context()->debug_specpars ? ALWAYS :
DEBUG,
1091 "+++ Parameter for %s: %s value %s is a %s",
1092 specParName.c_str(),
1100 if (
idx == string::npos &&
type ==
"number") {
1101 registry.specpars[specParName].numpars[
name].emplace_back(dd4hep::_toDouble(
value));
1104 if (
idx == string::npos ||
type ==
"string") {
1109 while (
idx != string::npos) {
1113 if (idp == string::npos || idp > idq)
1115 else if (idp != string::npos && idp < idq)
1123 for (
idx =
v.find(
'[', 0);
idx != string::npos;
idx =
v.find(
'[',
idx + 1)) {
1124 idq =
v.find(
']',
idx + 1);
1126 auto r = ns.context()->description.constants().find(
rep);
1127 if (
r != ns.context()->description.constants().end()) {
1128 rep =
"(" +
r->second->type +
")";
1132 registry.specpars[specParName].numpars[
name].emplace_back(dd4hep::_toDouble(
value));
1135 template <
typename TYPE>
1138 xml_dim_t
e(element);
1139 string nam =
e.nameStr();
1140 string solidName[2];
1144 if (
e.hasChild(
DD_CMU(rSolid))) {
1145 for (xml_coll_t
c(element,
DD_CMU(rSolid)); cnt < 2 &&
c; ++
c, ++cnt) {
1146 solidName[cnt] =
c.attr<
string>(_U(
name));
1147 solids[cnt] = ns.
solid(
c.attr<
string>(_U(
name)));
1150 solidName[0] =
e.attr<
string>(
DD_CMU(firstSolid));
1153 solidName[1] =
e.attr<
string>(
DD_CMU(secondSolid));
1158 except(
"DD4CMS",
"+++ Failed to create boolean solid %s. Found only %d parts.", nam.c_str(), cnt);
1165 "+++ BooleanSolid: %s Left: %-32s Right: %-32s",
1167 ((solids[0].ptr() ==
nullptr) ? solidName[0].c_str() : solids[0]->GetName()),
1168 ((solids[1].ptr() ==
nullptr) ? solidName[1].c_str() : solids[1]->GetName()));
1174 Converter<DDLTransform3D>(
context->description,
context, &trafo)(element);
1175 boolean =
TYPE(solids[0], solids[1], trafo);
1179 Converter<DDLTransform3D>(
context->description,
context, &trafo)(element);
1192 void Converter<DDLUnionSolid>::operator()(xml_h element)
const {
1193 convert_boolean<UnionSolid>(_param<cms::DDParsingContext>(), element);
1198 void Converter<DDLSubtractionSolid>::operator()(xml_h element)
const {
1199 convert_boolean<SubtractionSolid>(_param<cms::DDParsingContext>(), element);
1204 void Converter<DDLIntersectionSolid>::operator()(xml_h element)
const {
1205 convert_boolean<IntersectionSolid>(_param<cms::DDParsingContext>(), element);
1210 void Converter<DDLPolycone>::operator()(xml_h element)
const {
1212 xml_dim_t
e(element);
1213 string nam =
e.nameStr();
1214 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1216 vector<double>
z, rmin, rmax,
r;
1218 for (xml_coll_t rzpoint(element,
DD_CMU(RZPoint)); rzpoint; ++rzpoint) {
1219 z.emplace_back(ns.attr<
double>(rzpoint, _U(
z)));
1220 r.emplace_back(ns.attr<
double>(rzpoint, _U(
r)));
1223 for (xml_coll_t zplane(element,
DD_CMU(ZSection)); zplane; ++zplane) {
1224 rmin.emplace_back(ns.attr<
double>(zplane,
DD_CMU(
rMin)));
1225 rmax.emplace_back(ns.attr<
double>(zplane,
DD_CMU(
rMax)));
1226 z.emplace_back(ns.attr<
double>(zplane, _U(
z)));
1231 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1233 "+ Polycone: startPhi=%10.3f [rad] deltaPhi=%10.3f [rad] %4ld z-planes",
1240 ns.addSolid(nam, Polycone(startPhi,
deltaPhi, rmin, rmax,
z));
1244 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1246 "+ Polycone: startPhi=%10.3f [rad] deltaPhi=%10.3f [rad] %4ld z-planes and %4ld radii",
1254 ns.addSolid(nam, Polycone(startPhi,
deltaPhi,
r,
z));
1260 void Converter<DDLExtrudedPolygon>::operator()(xml_h element)
const {
1262 xml_dim_t
e(element);
1263 string nam =
e.nameStr();
1264 vector<double> pt_x, pt_y, sec_x, sec_y, sec_z, sec_scale;
1267 sec_z.emplace_back(ns.attr<
double>(
sec, _U(
z)));
1268 sec_x.emplace_back(ns.attr<
double>(
sec, _U(
x)));
1269 sec_y.emplace_back(ns.attr<
double>(
sec, _U(
y)));
1270 sec_scale.emplace_back(ns.attr<
double>(
sec,
DD_CMU(
scale), 1.0));
1272 for (xml_coll_t
pt(element,
DD_CMU(XYPoint));
pt; ++
pt) {
1273 pt_x.emplace_back(ns.attr<
double>(
pt, _U(
x)));
1274 pt_y.emplace_back(ns.attr<
double>(
pt, _U(
y)));
1279 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1281 "+ ExtrudedPolygon: %4ld points %4ld zxy sections",
1287 ns.addSolid(nam,
ExtrudedPolygon(pt_x, pt_y, sec_z, sec_x, sec_y, sec_scale));
1292 void Converter<DDLPolyhedra>::operator()(xml_h element)
const {
1294 xml_dim_t
e(element);
1295 string nam =
e.nameStr();
1296 double numSide = ns.attr<
int>(
e,
DD_CMU(numSide));
1297 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1299 vector<double>
z, rmin, rmax;
1301 for (xml_coll_t zplane(element,
DD_CMU(RZPoint)); zplane; ++zplane) {
1302 rmin.emplace_back(0.0);
1303 rmax.emplace_back(ns.attr<
double>(zplane, _U(
r)));
1304 z.emplace_back(ns.attr<
double>(zplane, _U(
z)));
1306 for (xml_coll_t zplane(element,
DD_CMU(ZSection)); zplane; ++zplane) {
1307 rmin.emplace_back(ns.attr<
double>(zplane,
DD_CMU(
rMin)));
1308 rmax.emplace_back(ns.attr<
double>(zplane,
DD_CMU(
rMax)));
1309 z.emplace_back(ns.attr<
double>(zplane, _U(
z)));
1314 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1316 "+ Polyhedra:startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] %4d sides %4ld z-planes",
1329 void Converter<DDLSphere>::operator()(xml_h element)
const {
1331 xml_dim_t
e(element);
1332 string nam =
e.nameStr();
1335 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1337 double startTheta = ns.attr<
double>(
e,
DD_CMU(startTheta));
1338 double deltaTheta = ns.attr<
double>(
e,
DD_CMU(deltaTheta));
1342 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1344 "+ Sphere: r_inner=%8.3f [cm] r_outer=%8.3f [cm]"
1345 " startPhi=%8.3f [rad] deltaPhi=%8.3f startTheta=%8.3f delteTheta=%8.3f [rad]",
1346 rinner / dd4hep::cm,
1347 router / dd4hep::cm,
1355 ns.addSolid(nam, Sphere(rinner, router, startTheta, deltaTheta, startPhi,
deltaPhi));
1360 void Converter<DDLTorus>::operator()(xml_h element)
const {
1362 xml_dim_t
e(element);
1363 string nam =
e.nameStr();
1364 double r = ns.attr<
double>(
e,
DD_CMU(torusRadius));
1367 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1372 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1374 "+ Torus: r=%10.3f [cm] r_inner=%10.3f [cm] r_outer=%10.3f [cm]"
1375 " startPhi=%10.3f [rad] deltaPhi=%10.3f [rad]",
1377 rinner / dd4hep::cm,
1378 router / dd4hep::cm,
1384 ns.addSolid(nam, Torus(
r, rinner, router, startPhi,
deltaPhi));
1389 void Converter<DDLPseudoTrap>::operator()(xml_h element)
const {
1391 xml_dim_t
e(element);
1392 string nam =
e.nameStr();
1393 double dx1 = ns.attr<
double>(
e,
DD_CMU(dx1));
1394 double dy1 = ns.attr<
double>(
e,
DD_CMU(dy1));
1395 double dx2 = ns.attr<
double>(
e,
DD_CMU(dx2));
1396 double dy2 = ns.attr<
double>(
e,
DD_CMU(dy2));
1397 double dz = ns.attr<
double>(
e, _U(
dz));
1398 double r = ns.attr<
double>(
e, _U(
radius));
1399 bool atMinusZ = ns.attr<
bool>(
e,
DD_CMU(atMinusZ));
1403 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1405 "+ Pseudotrap: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2=%.3f dy2=%.3f radius:%.3f atMinusZ:%s",
1416 ns.addSolid(nam, PseudoTrap(dx1, dx2, dy1, dy2,
dz,
r, atMinusZ));
1421 void Converter<DDLTrapezoid>::operator()(xml_h element)
const {
1423 xml_dim_t
e(element);
1424 string nam =
e.nameStr();
1425 double dz = ns.attr<
double>(
e, _U(
dz));
1426 double alp1 = ns.attr<
double>(
e,
DD_CMU(alp1));
1427 double bl1 = ns.attr<
double>(
e,
DD_CMU(bl1));
1428 double tl1 = ns.attr<
double>(
e,
DD_CMU(tl1));
1429 double h1 = ns.attr<
double>(
e,
DD_CMU(h1));
1430 double alp2 = ns.attr<
double>(
e,
DD_CMU(alp2));
1431 double bl2 = ns.attr<
double>(
e,
DD_CMU(bl2));
1432 double tl2 = ns.attr<
double>(
e,
DD_CMU(tl2));
1433 double h2 = ns.attr<
double>(
e,
DD_CMU(h2));
1434 double phi = ns.attr<
double>(
e, _U(
phi), 0.0);
1435 double theta = ns.attr<
double>(
e, _U(
theta), 0.0);
1439 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1441 "+ Trapezoid: dz=%10.3f [cm] alp1:%.3f bl1=%.3f tl1=%.3f alp2=%.3f bl2=%.3f tl2=%.3f h2=%.3f phi=%.3f "
1457 ns.addSolid(nam, Trap(
dz,
theta,
phi, h1, bl1, tl1, alp1, h2, bl2, tl2, alp2));
1462 void Converter<DDLTrd1>::operator()(xml_h element)
const {
1464 xml_dim_t
e(element);
1465 string nam =
e.nameStr();
1466 double dx1 = ns.attr<
double>(
e,
DD_CMU(dx1));
1467 double dy1 = ns.attr<
double>(
e,
DD_CMU(dy1));
1468 double dx2 = ns.attr<
double>(
e,
DD_CMU(dx2), 0.0);
1469 double dy2 = ns.attr<
double>(
e,
DD_CMU(dy2), dy1);
1474 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1476 "+ Trd1: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1485 ns.addSolid(nam, Trd1(dx1, dx2, dy1,
dz));
1489 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1491 "+ Trd1(which is actually Trd2): dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1500 ns.addSolid(nam, Trd2(dx1, dx2, dy1, dy2,
dz));
1506 void Converter<DDLTrd2>::operator()(xml_h element)
const {
1508 xml_dim_t
e(element);
1509 string nam =
e.nameStr();
1510 double dx1 = ns.attr<
double>(
e,
DD_CMU(dx1));
1511 double dy1 = ns.attr<
double>(
e,
DD_CMU(dy1));
1512 double dx2 = ns.attr<
double>(
e,
DD_CMU(dx2), 0.0);
1513 double dy2 = ns.attr<
double>(
e,
DD_CMU(dy2), dy1);
1518 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1520 "+ Trd1: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1529 ns.addSolid(nam, Trd2(dx1, dx2, dy1, dy2,
dz));
1534 void Converter<DDLTubs>::operator()(xml_h element)
const {
1536 xml_dim_t
e(element);
1537 string nam =
e.nameStr();
1541 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi), 0.0);
1546 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1548 "+ Tubs: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
1549 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]",
1558 ns.addSolid(nam, Tube(rmin, rmax,
dz, startPhi, startPhi +
deltaPhi));
1563 void Converter<DDLCutTubs>::operator()(xml_h element)
const {
1565 xml_dim_t
e(element);
1566 string nam =
e.nameStr();
1570 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1572 double lx = ns.attr<
double>(
e,
DD_CMU(lx));
1573 double ly = ns.attr<
double>(
e,
DD_CMU(ly));
1574 double lz = ns.attr<
double>(
e,
DD_CMU(lz));
1575 double tx = ns.attr<
double>(
e,
DD_CMU(tx));
1576 double ty = ns.attr<
double>(
e,
DD_CMU(ty));
1577 double tz = ns.attr<
double>(
e,
DD_CMU(tz));
1581 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1583 "+ CutTube: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
1584 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]...",
1593 ns.addSolid(nam, CutTube(rmin, rmax,
dz, startPhi, startPhi +
deltaPhi, lx, ly, lz, tx, ty, tz));
1598 void Converter<DDLTruncTubs>::operator()(xml_h element)
const {
1600 xml_dim_t
e(element);
1601 string nam =
e.nameStr();
1602 double zhalf = ns.attr<
double>(
e,
DD_CMU(zHalf));
1605 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1607 double cutAtStart = ns.attr<
double>(
e,
DD_CMU(cutAtStart));
1608 double cutAtDelta = ns.attr<
double>(
e,
DD_CMU(cutAtDelta));
1609 bool cutInside = ns.attr<
bool>(
e,
DD_CMU(cutInside));
1613 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1615 "+ TruncTube:zHalf=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
1616 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] atStart=%8.3f [cm] atDelta=%8.3f [cm] inside:%s",
1622 cutAtStart / dd4hep::cm,
1623 cutAtDelta / dd4hep::cm,
1628 ns.addSolid(nam, TruncatedTube(zhalf, rmin, rmax, startPhi,
deltaPhi, cutAtStart, cutAtDelta, cutInside));
1633 void Converter<DDLEllipticalTube>::operator()(xml_h element)
const {
1635 xml_dim_t
e(element);
1636 string nam =
e.nameStr();
1637 double dx = ns.attr<
double>(
e,
DD_CMU(xSemiAxis));
1638 double dy = ns.attr<
double>(
e,
DD_CMU(ySemiAxis));
1639 double dz = ns.attr<
double>(
e,
DD_CMU(zHeight));
1643 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1645 "+ EllipticalTube xSemiAxis=%8.3f [cm] ySemiAxis=%8.3f [cm] zHeight=%8.3f [cm]",
1652 ns.addSolid(nam, EllipticalTube(
dx,
dy,
dz));
1657 void Converter<DDLCone>::operator()(xml_h element)
const {
1659 xml_dim_t
e(element);
1660 string nam =
e.nameStr();
1662 double rmin1 = ns.attr<
double>(
e,
DD_CMU(rMin1));
1663 double rmin2 = ns.attr<
double>(
e,
DD_CMU(rMin2));
1664 double rmax1 = ns.attr<
double>(
e,
DD_CMU(rMax1));
1665 double rmax2 = ns.attr<
double>(
e,
DD_CMU(rMax2));
1666 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1672 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1674 "+ Cone: dz=%8.3f [cm]"
1675 " rmin1=%8.3f [cm] rmax1=%8.3f [cm]"
1676 " rmin2=%8.3f [cm] rmax2=%8.3f [cm]"
1677 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]",
1688 ns.addSolid(nam, ConeSegment(
dz, rmin1, rmax1, rmin2, rmax2, startPhi, phi2));
1693 void Converter<DDLShapeless>::operator()(xml_h element)
const {
1695 xml_dim_t
e(element);
1696 string nam =
e.nameStr();
1700 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1702 "+ Shapeless: THIS ONE CAN ONLY BE USED AT THE VOLUME LEVEL -> Shapeless: %s",
1707 ns.addSolid(nam, Box(1, 1, 1));
1712 void Converter<DDLAssembly>::operator()(xml_h element)
const {
1714 xml_dim_t
e(element);
1715 string nam =
e.nameStr();
1719 ns.context()->debug_shapes ? ALWAYS :
DEBUG,
"DD4CMS",
"+ Assembly: Adding solid -> Assembly: %s", nam.c_str());
1722 ns.addAssemblySolid(nam);
1727 void Converter<DDLBox>::operator()(xml_h element)
const {
1729 xml_dim_t
e(element);
1730 string nam =
e.nameStr();
1737 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1739 "+ Box: dx=%10.3f [cm] dy=%10.3f [cm] dz=%10.3f [cm]",
1746 ns.addSolid(nam, Box(
dx,
dy,
dz));
1751 void Converter<include_load>::operator()(xml_h element)
const {
1752 string fname = element.attr<
string>(_U(ref));
1755 doc = xml::DocumentHandler().load(
fp.fullPath());
1759 printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS :
DEBUG,
1761 "+++ Processing the CMS detector description %s",
1766 _option<DDRegistry>()->includes.emplace_back(
doc);
1771 void Converter<include_unload>::operator()(xml_h element)
const {
1772 string fname = xml::DocumentHandler::system_path(element);
1773 xml::DocumentHolder(xml_elt_t(element).document()).assign(
nullptr);
1777 printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS :
DEBUG,
1779 "+++ Finished processing %s",
1786 void Converter<include_constants>::operator()(xml_h element)
const {
1799 const std::map<std::string, DDAxes> axesmap{{
"x",
DDAxes::x},
1809 void Converter<DDLDivision>::operator()(xml_h element)
const {
1811 xml_dim_t
e(element);
1812 string childName =
e.nameStr();
1814 childName = ns.prepend(childName);
1818 parentName = ns.prepend(parentName);
1819 string axis = ns.attr<
string>(
e,
DD_CMU(axis));
1825 int nReplicas =
e.hasAttr(
DD_CMU(nReplicas)) ? ns.attr<
int>(
e,
DD_CMU(nReplicas)) : 0;
1829 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1831 "+++ Start executing Division of %s along %s (%d) with offset %6.3f and %6.3f to produce %s....",
1843 const TGeoShape* shape =
parent.solid();
1844 TClass*
cl = shape->IsA();
1846 const TGeoTubeSeg* sh = (
const TGeoTubeSeg*)shape;
1849 int numCopies = (
int)((sh->GetPhi2() - sh->GetPhi1()) / widthInDeg);
1853 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1855 "+++ ...divide %s along %s (%d) with offset %6.3f deg and %6.3f deg to produce %d copies",
1865 Volume child =
parent.divide(childName, static_cast<int>(axesmap.at(axis)), numCopies, startInDeg, widthInDeg);
1867 ns.context()->volumes[childName] =
child;
1871 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1873 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] is multivolume [%s]",
1876 parent.isValid() ?
"VALID" :
"INVALID",
1878 child.isValid() ?
"VALID" :
"INVALID",
1879 child->IsVolumeMulti() ?
"YES" :
"NO");
1883 double dy = static_cast<const TGeoTrd1*>(shape)->GetDy();
1887 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1889 "+++ ...divide %s along %s (%d) with offset %6.3f cm and %6.3f cm to produce %d copies in %6.3f",
1902 ns.context()->volumes[childName] =
child;
1906 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1908 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] is multivolume [%s]",
1911 parent.isValid() ?
"VALID" :
"INVALID",
1913 child.isValid() ?
"VALID" :
"INVALID",
1914 child->IsVolumeMulti() ?
"YES" :
"NO");
1918 printout(
ERROR,
"DD4CMS",
"++ FAILED Division of a %s is not implemented yet!",
parent.solid().type());
1924 void Converter<DDLAlgorithm>::operator()(xml_h element)
const {
1926 xml_dim_t
e(element);
1927 string name =
e.nameStr();
1929 string type =
"DDCMS_" + ns.realName(
name);
1936 ns.context()->debug_algorithms ? ALWAYS :
DEBUG,
"DD4CMS",
"+++ Start executing algorithm %s....",
type.c_str());
1944 printout(ns.context()->debug_algorithms ? ALWAYS :
DEBUG,
1947 "+++ Executed algorithm: %08lX = %s",
1954 printout(
ERROR,
"DD4CMS",
"++ FAILED NOT ADDING SUBDETECTOR %08lX = %s",
ret,
name.c_str());
1957 template <
class InputIt,
class ForwardIt,
class BinOp>
1960 const auto pos = std::find_first_of(
first,
last, s_first, s_last);
1970 std::vector<string>
splitString(
const string&
str,
const string& delims =
",") {
1971 std::vector<string>
output;
1985 std::vector<double> splitNumeric(
const string&
str,
const string& delims =
",") {
1986 std::vector<double>
output;
2004 void Converter<DDLVector>::operator()(xml_h element)
const {
2008 xml_dim_t
e(element);
2009 string name = ns.prepend(
e.nameStr());
2010 string type = ns.attr<
string>(
e, _U(
type));
2011 string nEntries = ns.attr<
string>(
e,
DD_CMU(nEntries));
2012 string val =
e.text();
2013 val.erase(remove_if(
val.begin(),
val.end(), [](
unsigned char x) {
return isspace(x); }),
val.end());
2017 printout(ns.context()->debug_constants ? ALWAYS :
DEBUG,
2019 "+++ Vector<%s>: %s[%s]: %s",
2028 std::vector<double>
results = splitNumeric(
val);
2037 "++ Unresolved Vector<%s>: %s[%s]: %s. Try to resolve later. [%s]",
2052 void Converter<debug>::operator()(xml_h dbg)
const {
2054 if (dbg.hasChild(
DD_CMU(debug_constants)))
2055 ns.setContext()->debug_constants =
true;
2056 if (dbg.hasChild(
DD_CMU(debug_materials)))
2057 ns.setContext()->debug_materials =
true;
2058 if (dbg.hasChild(
DD_CMU(debug_rotations)))
2059 ns.setContext()->debug_rotations =
true;
2060 if (dbg.hasChild(
DD_CMU(debug_shapes)))
2061 ns.setContext()->debug_shapes =
true;
2062 if (dbg.hasChild(
DD_CMU(debug_volumes)))
2063 ns.setContext()->debug_volumes =
true;
2064 if (dbg.hasChild(
DD_CMU(debug_placements)))
2065 ns.setContext()->debug_placements =
true;
2066 if (dbg.hasChild(
DD_CMU(debug_namespaces)))
2067 ns.setContext()->debug_namespaces =
true;
2068 if (dbg.hasChild(
DD_CMU(debug_includes)))
2069 ns.setContext()->debug_includes =
true;
2070 if (dbg.hasChild(
DD_CMU(debug_algorithms)))
2071 ns.setContext()->debug_algorithms =
true;
2072 if (dbg.hasChild(
DD_CMU(debug_specpars)))
2073 ns.setContext()->debug_specpars =
true;
2077 void Converter<DDRegistry>::operator()(xml_h )
const {
2079 DDRegistry*
res = _option<DDRegistry>();
2087 "+++ RESOLVING %ld unknown constants..... (out of %ld)",
2088 res->unresolvedConst.size(),
2089 res->originalConst.size());
2092 while (!
res->unresolvedConst.empty()) {
2093 for (
auto&
i :
res->unresolvedConst) {
2094 const string&
n =
i.first;
2096 string&
v =
i.second;
2098 for (
idx =
v.find(
'[', 0);
idx != string::npos;
idx =
v.find(
'[',
idx + 1)) {
2099 idq =
v.find(
']',
idx + 1);
2101 auto r =
res->originalConst.find(
rep);
2102 if (
r !=
res->originalConst.end()) {
2103 rep =
"(" + (*r).second +
")";
2107 if (
v.find(
']') == string::npos) {
2108 if (
v.find(
"-+") != string::npos ||
v.find(
"+-") != string::npos) {
2109 while ((
idx =
v.find(
"-+")) != string::npos)
2110 v.replace(
idx, 2,
"-");
2111 while ((
idx =
v.find(
"+-")) != string::npos)
2112 v.replace(
idx, 2,
"-");
2119 "+++ [%06ld] ---------- %-40s = %s",
2120 res->unresolvedConst.size() - 1,
2122 res->originalConst[
n].c_str());
2126 ns.addConstantNS(
n,
v,
"number");
2127 res->unresolvedConst.erase(
n);
2131 if (++
count > 10000)
2134 if (!
res->unresolvedConst.empty()) {
2135 for (
const auto&
e :
res->unresolvedConst)
2136 printout(
ERROR,
"DD4CMS",
"+++ Unresolved constant: %-40s = %s.",
e.first.c_str(),
e.second.c_str());
2137 except(
"DD4CMS",
"++ FAILED to resolve %ld constant entries:",
res->unresolvedConst.size());
2139 res->unresolvedConst.clear();
2140 res->originalConst.clear();
2144 void Converter<print_xml_doc>::operator()(xml_h element)
const {
2145 string fname = xml::DocumentHandler::system_path(element);
2149 printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS :
DEBUG,
2151 "+++ Processing data from: %s",
2159 xml_elt_t dddef(element);
2163 ns.addConstantNS(
"world_x",
"101*m",
"number");
2164 ns.addConstantNS(
"world_y",
"101*m",
"number");
2165 ns.addConstantNS(
"world_z",
"450*m",
"number");
2166 ns.addConstantNS(
"Air",
"materials:Air",
"string");
2167 ns.addConstantNS(
"Vacuum",
"materials:Vacuum",
"string");
2169 string fname = xml::DocumentHandler::system_path(element);
2170 bool open_geometry = dddef.hasChild(
DD_CMU(open_geometry)) ? dddef.child(
DD_CMU(open_geometry)) :
true;
2171 bool close_geometry = dddef.hasChild(
DD_CMU(close_geometry)) ? dddef.hasChild(
DD_CMU(close_geometry)) :
true;
2173 xml_coll_t(dddef, _U(
debug)).for_each(Converter<debug>(det, &
context));
2178 printout(
INFO,
"DD4CMS",
"+++ Processing the CMS detector description %s",
fname.c_str());
2181 Converter<print_xml_doc> print_doc(det, &
context);
2184 res.unresolvedConst.reserve(2000);
2185 res.originalConst.reserve(6000);
2186 print_doc((
doc = dddef.document()).
root());
2187 xml_coll_t(dddef,
DD_CMU(ConstantsSection)).for_each(Converter<ConstantsSection>(det, &
context, &
res));
2188 xml_coll_t(dddef,
DD_CMU(RotationSection)).for_each(Converter<RotationSection>(det, &
context));
2189 xml_coll_t(dddef,
DD_CMU(MaterialSection)).for_each(Converter<MaterialSection>(det, &
context));
2191 xml_coll_t(dddef,
DD_CMU(IncludeSection)).for_each(
DD_CMU(Include), Converter<include_load>(det, &
context, &
res));
2193 for (xml::Document
d :
res.includes) {
2198 Converter<DDRegistry>(det, &
context, &
res)(dddef);
2204 "+++ RESOLVING %ld Vectors.....",
2205 context.unresolvedVectors.size());
2207 while (!
context.unresolvedVectors.empty()) {
2208 for (
auto it =
context.unresolvedVectors.begin(); it !=
context.unresolvedVectors.end();) {
2209 std::vector<double>
result;
2210 for (
const auto&
i : it->second) {
2211 result.emplace_back(dd4hep::_toDouble(
i));
2213 registry->insert({it->first,
result});
2215 it =
context.unresolvedVectors.erase(it);
2220 for (xml::Document
d :
res.includes) {
2222 xml_coll_t(
d.root(),
DD_CMU(MaterialSection)).for_each(Converter<MaterialSection>(det, &
context));
2227 "+++ RESOLVING %ld unknown material constituents.....",
2228 context.unresolvedMaterials.size());
2232 while (!
context.unresolvedMaterials.empty()) {
2233 for (
auto it =
context.unresolvedMaterials.begin(); it !=
context.unresolvedMaterials.end();) {
2234 auto const&
name = it->first;
2235 std::vector<bool>
valid;
2239 "+++ [%06ld] ---------- %s",
2240 context.unresolvedMaterials.size(),
2243 auto mat = ns.material(
name);
2244 for (
auto& mit : it->second) {
2247 "+++ component %-48s Fraction: %.6f",
2250 auto fmat = ns.material(mit.name);
2251 if (
nullptr != fmat.ptr()) {
2252 if (mat.ptr()->GetMaterial()->IsMixture()) {
2253 valid.emplace_back(
true);
2254 static_cast<TGeoMixture*>(mat.ptr()->GetMaterial())
2255 ->AddElement(fmat.ptr()->GetMaterial(), mit.fraction);
2260 if (
valid.size() == it->second.size())
2261 it =
context.unresolvedMaterials.erase(it);
2269 if (open_geometry) {
2271 ns.addVolume(det.worldVolume());
2273 for (xml::Document
d :
res.includes) {
2275 xml_coll_t(
d.root(),
DD_CMU(RotationSection)).for_each(Converter<RotationSection>(det, &
context));
2277 for (xml::Document
d :
res.includes) {
2279 xml_coll_t(
d.root(),
DD_CMU(SolidSection)).for_each(Converter<SolidSection>(det, &
context));
2281 for (xml::Document
d :
res.includes) {
2283 xml_coll_t(
d.root(),
DD_CMU(LogicalPartSection)).for_each(Converter<LogicalPartSection>(det, &
context));
2285 for (xml::Document
d :
res.includes) {
2289 for (xml::Document
d :
res.includes) {
2291 xml_coll_t(
d.root(),
DD_CMU(PosPartSection)).for_each(Converter<PosPartSection>(det, &
context));
2293 for (xml::Document
d :
res.includes) {
2295 xml_coll_t(
d.root(),
DD_CMU(SpecParSection)).for_each(Converter<SpecParSection>(det, &
context));
2299 for (xml::Document
d :
res.includes)
2300 Converter<include_unload>(det, &
context, &
res)(
d.root());
2302 print_doc((
doc = dddef.document()).
root());
2304 xml_coll_t(dddef,
DD_CMU(SolidSection)).for_each(Converter<SolidSection>(det, &
context));
2311 while (!
context.unresolvedShapes.empty()) {
2312 for (
auto it =
context.unresolvedShapes.begin(); it !=
context.unresolvedShapes.end();) {
2313 auto const&
name = it->first;
2314 auto const& aname = std::visit([](
auto&&
arg) ->
std::string {
return arg.firstSolidName; }, it->second);
2315 auto const& bname = std::visit([](
auto&&
arg) ->
std::string {
return arg.secondSolidName; }, it->second);
2317 auto const& ait =
context.shapes.find(aname);
2318 if (ait->second.isValid()) {
2319 auto const& bit =
context.shapes.find(bname);
2320 if (bit->second.isValid()) {
2321 dd4hep::Solid shape =
2322 std::visit([&ait, &bit](
auto&&
arg) -> dd4hep::Solid {
return arg.make(ait->second, bit->second); },
2325 it =
context.unresolvedShapes.erase(it);
2333 xml_coll_t(dddef,
DD_CMU(LogicalPartSection)).for_each(Converter<LogicalPartSection>(det, &
context));
2335 xml_coll_t(dddef,
DD_CMU(PosPartSection)).for_each(Converter<PosPartSection>(det, &
context));
2336 xml_coll_t(dddef,
DD_CMU(SpecParSection)).for_each(Converter<SpecParSection>(det, &
context));
2338 printout(
ERROR,
"DD4CMS",
"Exception while processing xml source:%s",
doc.uri().c_str());
2339 printout(
ERROR,
"DD4CMS",
"----> %s",
e.what());
2344 if (close_geometry) {
2346 Volume geomv = ns.volume(
"cms:OCMS",
false);
2347 if (geomv.isValid())
2348 wv.placeVolume(geomv, 1);
2349 Volume mfv = ns.volume(
"cmsMagneticField:MAGF",
false);
2351 wv.placeVolume(mfv, 1);
2352 Volume mfv1 = ns.volume(
"MagneticFieldVolumes:MAGF",
false);
2354 wv.placeVolume(mfv1, 1);
2357 det.manager().CloseGeometry();
2361 printout(
INFO,
"DDDefinition",
"+++ Finished processing %s",
fname.c_str());
2364 except(
"DDDefinition",
"+++ FAILED to process unknown DOM tree [Invalid Handle]");