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" 22 #include "TGeoManager.h" 23 #include "TGeoMaterial.h" 30 #include <unordered_map> 44 atomic<UInt_t> unique_mat_id = 0xAFFEFEED;
46 class include_constants;
51 class ConstantsSection;
60 class MaterialSection;
64 class RotationSection;
66 class DDLReflectionRotation;
75 class LogicalPartSection;
79 class DDLExtrudedPolygon;
97 class DDLIntersectionSolid;
98 class DDLSubtractionSolid;
103 class SpecParSection;
117 TGeoTranslation
t(iTrans.x(), iTrans.y(), iTrans.z());
119 return new TGeoCombiTrans(
t,
r);
124 void Converter<debug>::operator()(xml_h element)
const;
126 void Converter<print_xml_doc>::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<MaterialSection>::operator()(xml_h element)
const;
140 void Converter<DDLElementaryMaterial>::operator()(xml_h element)
const;
142 void Converter<DDLCompositeMaterial>::operator()(xml_h element)
const;
146 void Converter<RotationSection>::operator()(xml_h element)
const;
149 void Converter<DDLRotation>::operator()(xml_h element)
const;
152 void Converter<DDLReflectionRotation>::operator()(xml_h element)
const;
155 void Converter<DDLRotationSequence>::operator()(xml_h element)
const;
158 void Converter<DDLRotationByAxis>::operator()(xml_h element)
const;
160 void Converter<DDLTransform3D>::operator()(xml_h element)
const;
164 void Converter<LogicalPartSection>::operator()(xml_h element)
const;
166 void Converter<DDLLogicalPart>::operator()(xml_h element)
const;
170 void Converter<PosPartSection>::operator()(xml_h element)
const;
173 void Converter<DDLPosPart>::operator()(xml_h element)
const;
176 void Converter<DDLDivision>::operator()(xml_h element)
const;
180 void Converter<SpecParSection>::operator()(xml_h element)
const;
182 void Converter<DDLSpecPar>::operator()(xml_h element)
const;
184 void Converter<PartSelector>::operator()(xml_h element)
const;
186 void Converter<Parameter>::operator()(xml_h element)
const;
190 void Converter<SolidSection>::operator()(xml_h element)
const;
193 void Converter<DDLUnionSolid>::operator()(xml_h element)
const;
196 void Converter<DDLSubtractionSolid>::operator()(xml_h element)
const;
199 void Converter<DDLIntersectionSolid>::operator()(xml_h element)
const;
202 void Converter<DDLPseudoTrap>::operator()(xml_h element)
const;
205 void Converter<DDLExtrudedPolygon>::operator()(xml_h element)
const;
208 void Converter<DDLShapeless>::operator()(xml_h element)
const;
211 void Converter<DDLAssembly>::operator()(xml_h element)
const;
214 void Converter<DDLTrapezoid>::operator()(xml_h element)
const;
217 void Converter<DDLPolycone>::operator()(xml_h element)
const;
220 void Converter<DDLPolyhedra>::operator()(xml_h element)
const;
223 void Converter<DDLEllipticalTube>::operator()(xml_h element)
const;
226 void Converter<DDLTorus>::operator()(xml_h element)
const;
229 void Converter<DDLTubs>::operator()(xml_h element)
const;
232 void Converter<DDLCutTubs>::operator()(xml_h element)
const;
235 void Converter<DDLTruncTubs>::operator()(xml_h element)
const;
238 void Converter<DDLSphere>::operator()(xml_h element)
const;
241 void Converter<DDLTrd1>::operator()(xml_h element)
const;
244 void Converter<DDLTrd2>::operator()(xml_h element)
const;
247 void Converter<DDLCone>::operator()(xml_h element)
const;
250 void Converter<DDLBox>::operator()(xml_h element)
const;
253 void Converter<DDLAlgorithm>::operator()(xml_h element)
const;
256 void Converter<DDLVector>::operator()(xml_h element)
const;
260 void Converter<include_load>::operator()(xml_h element)
const;
263 void Converter<include_unload>::operator()(xml_h element)
const;
266 void Converter<include_constants>::operator()(xml_h element)
const;
271 void Converter<ConstantsSection>::operator()(xml_h element)
const {
280 void Converter<MaterialSection>::operator()(xml_h element)
const {
282 xml_coll_t(element,
DD_CMU(ElementaryMaterial))
284 xml_coll_t(element,
DD_CMU(CompositeMaterial))
289 void Converter<RotationSection>::operator()(xml_h element)
const {
292 xml_coll_t(element,
DD_CMU(ReflectionRotation))
294 xml_coll_t(element,
DD_CMU(RotationSequence))
296 xml_coll_t(element,
DD_CMU(RotationByAxis))
301 void Converter<PosPartSection>::operator()(xml_h element)
const {
309 void Converter<SpecParSection>::operator()(xml_h element)
const {
315 void Converter<DDLSpecPar>::operator()(xml_h element)
const {
323 void Converter<LogicalPartSection>::operator()(xml_h element)
const {
330 void Converter<SolidSection>::operator()(xml_h element)
const {
332 for (xml_coll_t solid(element, _U(star)); solid; ++solid) {
334 switch (
hash(solid.tag())) {
338 case hash(
"Polycone"):
341 case hash(
"Polyhedra"):
347 case hash(
"CutTubs"):
350 case hash(
"TruncTubs"):
368 case hash(
"EllipticalTube"):
374 case hash(
"PseudoTrap"):
377 case hash(
"ExtrudedPolygon"):
380 case hash(
"Trapezoid"):
383 case hash(
"UnionSolid"):
386 case hash(
"SubtractionSolid"):
389 case hash(
"IntersectionSolid"):
392 case hash(
"ShapelessSolid"):
395 case hash(
"Assembly"):
399 throw std::runtime_error(
"Request to process unknown shape '" + xml_dim_t(solid).nameStr() +
"' [" +
408 void Converter<DDLConstant>::operator()(xml_h element)
const {
410 DDRegistry*
res = _option<DDRegistry>();
411 xml_dim_t constant = element;
412 xml_dim_t par = constant.parent();
413 bool eval = par.hasAttr(_U(eval)) ? par.attr<
bool>(_U(eval)) :
true;
414 string val = constant.valueStr();
415 string nam = constant.nameStr();
416 string real = ns.prepend(nam);
417 string typ = eval ?
"number" :
"string";
418 size_t idx =
val.find(
'[');
420 if (constant.hasAttr(_U(
type)))
421 typ = constant.typeStr();
423 if (
idx == string::npos ||
typ ==
"string") {
425 ns.addConstant(nam,
val,
typ);
426 res->originalConst[real] =
val;
432 "++ Unresolved constant: %s = %s [%s]. Try to resolve later. [%s]",
442 while (
idx != string::npos) {
444 size_t idp =
val.find(
':',
idx);
445 size_t idq =
val.find(
']',
idx);
446 if (idp == string::npos || idp > idq)
447 val.insert(
idx, ns.name());
448 else if (idp != string::npos && idp < idq)
456 ns.context()->debug_constants ? ALWAYS :
DEBUG,
"Constant",
"Unresolved: %s -> %s", real.c_str(),
val.c_str());
460 res->originalConst[real] =
val;
461 res->unresolvedConst[real] =
val;
466 void Converter<DDLElementaryMaterial>::operator()(xml_h element)
const {
468 xml_dim_t xmat(element);
469 const string xmatName(xmat.nameStr());
470 string nam = ns.prepend(xmatName);
472 TGeoMaterial* mat = mgr.GetMaterial(nam.c_str());
473 if (
nullptr == mat) {
474 const char* matname = nam.c_str();
476 int atomicNumber = xmat.attr<
int>(
DD_CMU(atomicNumber));
477 double atomicWeight = xmat.attr<
double>(
DD_CMU(atomicWeight)) / (
dd4hep::g / dd4hep::mole);
478 TGeoElementTable* tab = mgr.GetElementTable();
479 int nElem = tab->GetNelements();
483 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
"DD4CMS",
"+++ Element table size = %d", nElem);
488 tab->TGeoElementTable::~TGeoElementTable();
489 new (tab) TGeoElementTable();
490 tab->BuildDefaultElements();
492 TGeoMixture*
mix =
new TGeoMixture(nam.c_str(), 1,
density);
493 const char*
const matNameNoNS = xmatName.c_str();
494 TGeoElement* elt = tab->FindElement(matNameNoNS);
498 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
500 "+++ Searching for material %-48s elt_ptr = %ld",
504 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
506 "+++ Converting material %-48s Atomic weight %8.3f [g/mol], Atomic number %u, Density: %8.3f [g/cm3] " 507 "ROOT: %8.3f [g/cm3]",
508 (
'"' + nam +
'"').c_str(),
516 bool newMatDef =
false;
523 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
525 " ROOT definition of %-50s Atomic weight %g, Atomic number %u, Number of nucleons %u",
530 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
532 "+++ Compared to XML values: Atomic weight %g, Atomic number %u",
537 static constexpr double const weightTolerance = 1.0e-6;
538 if (atomicNumber != elt->Z() ||
539 (
std::abs(atomicWeight - elt->A()) > (weightTolerance * (atomicWeight + elt->A()))))
543 if (!elt || newMatDef) {
547 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
549 "+++ Converter<ElementaryMaterial> Different definition of a default element with name:%s [CREATE NEW " 558 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
560 "+++ Converter<ElementaryMaterial> No default element present with name:%s [CREATE NEW MATERIAL]",
565 elt =
new TGeoElement(matNameNoNS, matNameNoNS, atomicNumber, atomicWeight);
568 mix->AddElement(elt, 1.0);
569 mix->SetTemperature(ns.context()->description.stdConditions().temperature);
570 mix->SetPressure(ns.context()->description.stdConditions().pressure);
573 TGeoMedium* medium = mgr.GetMedium(matname);
574 if (
nullptr == medium) {
576 medium =
new TGeoMedium(matname, unique_mat_id,
mix);
577 medium->SetTitle(
"material");
578 medium->SetUniqueID(unique_mat_id);
585 void Converter<DDLCompositeMaterial>::operator()(xml_h element)
const {
587 xml_dim_t xmat(element);
588 string nam = ns.prepend(xmat.nameStr());
591 TGeoMaterial* mat = mgr.GetMaterial(nam.c_str());
592 if (
nullptr == mat) {
594 xml_coll_t composites(xmat,
DD_CMU(MaterialFraction));
595 TGeoMixture*
mix =
new TGeoMixture(nam.c_str(), composites.size(),
density);
599 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
601 "++ Converting material %-48s Density: %8.3f [g/cm3] ROOT: %8.3f [g/cm3]",
602 (
'"' + nam +
'"').c_str(),
608 if (ns.context()->makePayload) {
609 ns.context()->compMaterialsVec.emplace_back(std::make_pair(nam,
density));
611 for (composites.reset(); composites; ++composites) {
612 xml_dim_t xfrac(composites);
613 xml_dim_t xfrac_mat(xfrac.child(
DD_CMU(rMaterial)));
615 string fracname = ns.realName(xfrac_mat.nameStr());
617 if (ns.context()->makePayload) {
618 ns.context()->compMaterialsRefs[nam].emplace_back(
621 TGeoMaterial* frac_mat = mgr.GetMaterial(fracname.c_str());
622 if (frac_mat ==
nullptr)
623 frac_mat = mgr.GetMaterial(ns.prepend(fracname).c_str());
629 throw cms::Exception(
"DD4CMS") <<
"Composite material \"" + fracname +
"\" or \"" + ns.prepend(fracname) +
630 "\" not yet defined.";
632 mix->SetTemperature(ns.context()->description.stdConditions().temperature);
633 mix->SetPressure(ns.context()->description.stdConditions().pressure);
636 TGeoMedium* medium = mgr.GetMedium(nam.c_str());
637 if (
nullptr == medium) {
639 medium =
new TGeoMedium(nam.c_str(), unique_mat_id,
mix);
640 medium->SetTitle(
"material");
641 medium->SetUniqueID(unique_mat_id);
648 void Converter<DDLRotation>::operator()(xml_h element)
const {
651 xml_dim_t xrot(element);
652 string nam = xrot.nameStr();
654 double phiX = xrot.hasAttr(
DD_CMU(phiX)) ? ns.attr<
double>(xrot,
DD_CMU(phiX)) : 0e0;
656 double phiY = xrot.hasAttr(
DD_CMU(phiY)) ? ns.attr<
double>(xrot,
DD_CMU(phiY)) : 0e0;
658 double phiZ = xrot.hasAttr(
DD_CMU(phiZ)) ? ns.attr<
double>(xrot,
DD_CMU(phiZ)) : 0e0;
665 "+++ Adding rotation: %-32s: (theta/phi)[rad] X: %6.3f %6.3f Y: %6.3f %6.3f Z: %6.3f %6.3f",
666 ns.prepend(nam).c_str(),
676 ns.addRotation(nam,
rot);
681 void Converter<DDLReflectionRotation>::operator()(xml_h element)
const {
684 xml_dim_t xrot(element);
685 string name = xrot.nameStr();
687 double phiX = xrot.hasAttr(
DD_CMU(phiX)) ? ns.attr<
double>(xrot,
DD_CMU(phiX)) : 0e0;
689 double phiY = xrot.hasAttr(
DD_CMU(phiY)) ? ns.attr<
double>(xrot,
DD_CMU(phiY)) : 0e0;
691 double phiZ = xrot.hasAttr(
DD_CMU(phiZ)) ? ns.attr<
double>(xrot,
DD_CMU(phiZ)) : 0e0;
697 "+++ Adding reflection rotation: %-32s: (theta/phi)[rad] X: %6.3f %6.3f Y: %6.3f %6.3f Z: %6.3f %6.3f",
698 ns.prepend(
name).c_str(),
714 void Converter<DDLRotationSequence>::operator()(xml_h element)
const {
717 xml_dim_t xrot(element);
718 string nam = xrot.nameStr();
720 xml_coll_t rotations(xrot,
DD_CMU(RotationByAxis));
721 for (rotations.reset(); rotations; ++rotations) {
722 string axis = ns.attr<
string>(rotations,
DD_CMU(axis));
723 double angle = ns.attr<
double>(rotations, _U(
angle));
730 "+ Adding rotation to: %-29s: (axis/angle)[rad] Axis: %s Angle: %6.3f",
746 "+++ Adding rotation sequence: %-23s: %6.3f %6.3f %6.3f, %6.3f %6.3f %6.3f, %6.3f %6.3f %6.3f",
747 ns.prepend(nam).c_str(),
760 ns.addRotation(nam,
rot);
765 void Converter<DDLRotationByAxis>::operator()(xml_h element)
const {
768 xml_dim_t xrot(element);
769 xml_dim_t par(xrot.parent());
770 if (xrot.hasAttr(_U(
name))) {
771 string nam = xrot.nameStr();
772 string axis = ns.attr<
string>(xrot,
DD_CMU(axis));
773 double angle = ns.attr<
double>(xrot, _U(
angle));
781 "+++ Adding rotation: %-32s: (axis/angle)[rad] Axis: %s Angle: %6.3f",
782 ns.prepend(nam).c_str(),
788 ns.addRotation(nam,
rot);
794 void Converter<DDLLogicalPart>::operator()(xml_h element)
const {
796 xml_dim_t
e(element);
798 string mat =
e.child(
DD_CMU(rMaterial)).attr<
string>(_U(
name));
799 string volName = ns.prepend(
e.attr<
string>(_U(
name)));
800 Solid solid = ns.solid(
sol);
801 Material material = ns.material(mat);
802 if (ns.context()->assemblySolids.count(
sol) == 1) {
806 ns.addAssembly(volName,
false);
814 ns.addVolume(
Volume(volName, solid, material));
818 printout(ns.context()->debug_volumes ? ALWAYS :
DEBUG,
820 "+++ %s Volume: %-24s [%s] Shape: %-32s [%s] Material: %-40s [%s]",
823 volume.isValid() ?
"VALID" :
"INVALID",
825 solid.isValid() ?
"VALID" :
"INVALID",
827 material.isValid() ?
"VALID" :
"INVALID");
834 void Converter<DDLTransform3D>::operator()(xml_h element)
const {
836 Transform3D* tr = _option<Transform3D>();
837 xml_dim_t
e(element);
840 xml_dim_t refRotation =
e.child(
DD_CMU(rRotation),
false);
841 xml_dim_t refReflectionRotation =
e.child(
DD_CMU(rReflectionRotation),
false);
845 if (translation.ptr()) {
846 double x = ns.attr<
double>(translation, _U(
x));
847 double y = ns.attr<
double>(translation, _U(
y));
848 double z = ns.attr<
double>(translation, _U(
z));
855 rot = RotationZYX(
z,
y,
x);
856 }
else if (refRotation.ptr()) {
857 string rotName = ns.prepend(refRotation.nameStr());
859 }
else if (refReflectionRotation.ptr()) {
860 string rotName = ns.prepend(refReflectionRotation.nameStr());
863 *tr = Transform3D(
rot,
pos);
867 const string& parentName,
869 const string& childName,
877 "+++ Parent vol: %-24s Child: %-32s, copy:%d",
884 TGeoShape*
shape = (*childPtr)->GetShape();
887 TGeoShapeAssembly* as = (TGeoShapeAssembly*)
shape;
891 as->NeedsBBoxRecompute();
897 TString nam_id = TString::Format(
"%s_%d", (*childPtr)->GetName(),
copy);
898 n =
static_cast<TGeoNode*
>((*parentPtr)->GetNode(nam_id));
900 printout(
ERROR,
"PlacedVolume",
"++ Attempt to add already existing node %s", (
const char*)nam_id);
906 if ((*childPtr)->IsAssembly()) {
913 printout(
ERROR,
"DD4CMS",
"+++ Placement FAILED! Parent:%s Child:%s", parentName.c_str(), childName.c_str());
919 void Converter<DDLPosPart>::operator()(xml_h element)
const {
921 xml_dim_t
e(element);
923 string parentName = ns.prepend(ns.attr<
string>(
e.child(
DD_CMU(rParent)), _U(
name)));
924 string childName = ns.prepend(ns.attr<
string>(
e.child(
DD_CMU(rChild)), _U(
name)));
930 Assembly parAsmb = ns.assembly(parentName,
false);
931 Assembly childAsmb = ns.assembly(childName,
false);
935 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
937 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] copy:%d",
940 parent.isValid() ?
"VALID" :
"INVALID",
942 child.isValid() ?
"VALID" :
"INVALID",
947 if (!
parent.isValid() && !parAsmb.isValid() && strchr(parentName.c_str(),
NAMESPACE_SEP) ==
nullptr) {
948 parentName = ns.prepend(parentName);
949 parAsmb = ns.assembly(parentName,
false);
950 if (!parAsmb.isValid())
951 parent = ns.volume(parentName);
954 if (!
child.isValid() && !childAsmb.isValid() && strchr(childName.c_str(),
NAMESPACE_SEP) ==
nullptr) {
955 childName = ns.prepend(childName);
956 child = ns.volume(childName,
false);
957 childAsmb = ns.assembly(childName,
false);
959 if (parAsmb.isValid() || childAsmb.isValid()) {
960 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
962 "***** Placing assembly parent %s, child %s",
965 Volume* parentPtr = parAsmb.isValid() ? &parAsmb : &
parent;
966 Volume* childPtr = childAsmb.isValid() ? &childAsmb : &
child;
973 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
975 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] copy:%d",
978 parent.isValid() ?
"VALID" :
"INVALID",
980 child.isValid() ?
"VALID" :
"INVALID",
986 if (
child.isValid()) {
991 except(
"dd4hep",
"Volume: Attempt to assign daughters to an invalid physical parent volume.");
994 except(
"dd4hep",
"Volume: Attempt to assign an invalid physical daughter volume.");
999 TGeoShapeAssembly* as = (TGeoShapeAssembly*)
shape;
1003 as->NeedsBBoxRecompute();
1008 TString nam_id = TString::Format(
"%s_%d",
child->GetName(),
copy);
1009 if (ns.context()->validate) {
1010 n =
static_cast<TGeoNode*
>(
parent->GetNode(nam_id));
1012 printout(
ERROR,
"PlacedVolume",
"++ Attempt to add already existing node %s", (
const char*)nam_id);
1017 Translation3D trans(
transform.Translation());
1019 trans.GetComponents(
x,
y,
z);
1023 n =
static_cast<TGeoNode*
>(
parent->GetNodes()->Last());
1024 assert(
n->GetName() == nam_id);
1025 n->TGeoNode::SetUserExtension(
new PlacedVolume::Object());
1028 if (!
pv.isValid()) {
1031 "+++ Placement FAILED! Parent:%s Child:%s Valid:%s",
1034 yes_no(
child.isValid()));
1040 void Converter<PartSelector>::operator()(xml_h element)
const {
1043 dd4hep::SpecParRegistry& registry = *
context->description.extension<dd4hep::SpecParRegistry>();
1044 xml_dim_t
e(element);
1045 xml_dim_t specPar =
e.parent();
1046 string specParName = specPar.attr<
string>(_U(
name));
1051 printout(ns.context()->debug_specpars ? ALWAYS :
DEBUG,
1053 "+++ PartSelector for %s path: %s",
1054 specParName.c_str(),
1059 size_t pos = std::string::npos;
1060 if ((
pos =
path.find(
"//.*:")) != std::string::npos) {
1063 registry.specpars[specParName].paths.emplace_back(
std::move(
path));
1068 void Converter<Parameter>::operator()(xml_h element)
const {
1071 dd4hep::SpecParRegistry& registry = *
context->description.extension<dd4hep::SpecParRegistry>();
1072 xml_dim_t
e(element);
1073 xml_dim_t specPar =
e.parent();
1074 xml_dim_t specParSect = specPar.parent();
1075 string specParName = specPar.attr<
string>(_U(
name));
1076 string name =
e.nameStr();
1078 bool eval = specParSect.hasAttr(_U(eval)) ? specParSect.attr<
bool>(_U(eval)) :
false;
1079 eval = specPar.hasAttr(_U(eval)) ? specPar.attr<
bool>(_U(eval)) : eval;
1080 eval =
e.hasAttr(_U(eval)) ?
e.attr<
bool>(_U(eval)) : eval;
1082 string type = eval ?
"number" :
"string";
1086 printout(ns.context()->debug_specpars ? ALWAYS :
DEBUG,
1088 "+++ Parameter for %s: %s value %s is a %s",
1089 specParName.c_str(),
1097 if (
idx == string::npos &&
type ==
"number") {
1098 registry.specpars[specParName].numpars[
name].emplace_back(dd4hep::_toDouble(
value));
1101 if (
idx == string::npos ||
type ==
"string") {
1106 while (
idx != string::npos) {
1110 if (idp == string::npos || idp > idq)
1112 else if (idp != string::npos && idp < idq)
1120 for (
idx =
v.find(
'[', 0);
idx != string::npos;
idx =
v.find(
'[',
idx + 1)) {
1121 idq =
v.find(
']',
idx + 1);
1123 auto r = ns.context()->description.constants().find(
rep);
1124 if (
r != ns.context()->description.constants().end()) {
1125 rep =
"(" +
r->second->type +
")";
1129 registry.specpars[specParName].numpars[
name].emplace_back(dd4hep::_toDouble(
value));
1132 template <
typename TYPE>
1135 xml_dim_t
e(element);
1136 string nam =
e.nameStr();
1137 string solidName[2];
1141 if (
e.hasChild(
DD_CMU(rSolid))) {
1142 for (xml_coll_t
c(element,
DD_CMU(rSolid)); cnt < 2 &&
c; ++
c, ++cnt) {
1143 solidName[cnt] =
c.attr<
string>(_U(
name));
1144 solids[cnt] = ns.
solid(
c.attr<
string>(_U(
name)));
1147 solidName[0] =
e.attr<
string>(
DD_CMU(firstSolid));
1150 solidName[1] =
e.attr<
string>(
DD_CMU(secondSolid));
1155 except(
"DD4CMS",
"+++ Failed to create boolean solid %s. Found only %d parts.", nam.c_str(), cnt);
1162 "+++ BooleanSolid: %s Left: %-32s Right: %-32s",
1164 ((solids[0].ptr() ==
nullptr) ? solidName[0].c_str() : solids[0]->GetName()),
1165 ((solids[1].ptr() ==
nullptr) ? solidName[1].c_str() : solids[1]->GetName()));
1171 Converter<DDLTransform3D>(
context->description,
context, &trafo)(element);
1172 boolean =
TYPE(solids[0], solids[1], trafo);
1176 Converter<DDLTransform3D>(
context->description,
context, &trafo)(element);
1179 if (solids[0].
isValid() ==
false) {
1180 printout(
ERROR,
"DD4CMS",
"++ Solid not defined yet: %s", solidName[0].c_str());
1182 if (solids[1].
isValid() ==
false) {
1183 printout(
ERROR,
"DD4CMS",
"++ Solid not defined yet: %s", solidName[1].c_str());
1185 printout(
ERROR,
"DD4CMS",
"++ Re-order XML files to prevent references to undefined solids");
1196 void Converter<DDLUnionSolid>::operator()(xml_h element)
const {
1197 convert_boolean<UnionSolid>(_param<cms::DDParsingContext>(), element);
1202 void Converter<DDLSubtractionSolid>::operator()(xml_h element)
const {
1203 convert_boolean<SubtractionSolid>(_param<cms::DDParsingContext>(), element);
1208 void Converter<DDLIntersectionSolid>::operator()(xml_h element)
const {
1209 convert_boolean<IntersectionSolid>(_param<cms::DDParsingContext>(), element);
1214 void Converter<DDLPolycone>::operator()(xml_h element)
const {
1216 xml_dim_t
e(element);
1217 string nam =
e.nameStr();
1218 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1220 vector<double>
z, rmin, rmax,
r;
1222 for (xml_coll_t rzpoint(element,
DD_CMU(RZPoint)); rzpoint; ++rzpoint) {
1223 z.emplace_back(ns.attr<
double>(rzpoint, _U(
z)));
1224 r.emplace_back(ns.attr<
double>(rzpoint, _U(
r)));
1227 for (xml_coll_t zplane(element,
DD_CMU(ZSection)); zplane; ++zplane) {
1228 rmin.emplace_back(ns.attr<
double>(zplane,
DD_CMU(
rMin)));
1229 rmax.emplace_back(ns.attr<
double>(zplane,
DD_CMU(
rMax)));
1230 z.emplace_back(ns.attr<
double>(zplane, _U(
z)));
1235 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1237 "+ Polycone: startPhi=%10.3f [rad] deltaPhi=%10.3f [rad] %4ld z-planes",
1244 ns.addSolid(nam, Polycone(startPhi,
deltaPhi, rmin, rmax,
z));
1248 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1250 "+ Polycone: startPhi=%10.3f [rad] deltaPhi=%10.3f [rad] %4ld z-planes and %4ld radii",
1258 ns.addSolid(nam, Polycone(startPhi,
deltaPhi,
r,
z));
1264 void Converter<DDLExtrudedPolygon>::operator()(xml_h element)
const {
1266 xml_dim_t
e(element);
1267 string nam =
e.nameStr();
1268 vector<double> pt_x, pt_y, sec_x, sec_y, sec_z, sec_scale;
1271 sec_z.emplace_back(ns.attr<
double>(
sec, _U(
z)));
1272 sec_x.emplace_back(ns.attr<
double>(
sec, _U(
x)));
1273 sec_y.emplace_back(ns.attr<
double>(
sec, _U(
y)));
1274 sec_scale.emplace_back(ns.attr<
double>(
sec,
DD_CMU(
scale), 1.0));
1276 for (xml_coll_t
pt(element,
DD_CMU(XYPoint));
pt; ++
pt) {
1277 pt_x.emplace_back(ns.attr<
double>(
pt, _U(
x)));
1278 pt_y.emplace_back(ns.attr<
double>(
pt, _U(
y)));
1283 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1285 "+ ExtrudedPolygon: %4ld points %4ld zxy sections",
1291 ns.addSolid(nam,
ExtrudedPolygon(pt_x, pt_y, sec_z, sec_x, sec_y, sec_scale));
1296 void Converter<DDLPolyhedra>::operator()(xml_h element)
const {
1298 xml_dim_t
e(element);
1299 string nam =
e.nameStr();
1300 double numSide = ns.attr<
int>(
e,
DD_CMU(numSide));
1301 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1303 vector<double>
z, rmin, rmax;
1305 for (xml_coll_t zplane(element,
DD_CMU(RZPoint)); zplane; ++zplane) {
1306 rmin.emplace_back(0.0);
1307 rmax.emplace_back(ns.attr<
double>(zplane, _U(
r)));
1308 z.emplace_back(ns.attr<
double>(zplane, _U(
z)));
1310 for (xml_coll_t zplane(element,
DD_CMU(ZSection)); zplane; ++zplane) {
1311 rmin.emplace_back(ns.attr<
double>(zplane,
DD_CMU(
rMin)));
1312 rmax.emplace_back(ns.attr<
double>(zplane,
DD_CMU(
rMax)));
1313 z.emplace_back(ns.attr<
double>(zplane, _U(
z)));
1318 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1320 "+ Polyhedra:startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] %4d sides %4ld z-planes",
1333 void Converter<DDLSphere>::operator()(xml_h element)
const {
1335 xml_dim_t
e(element);
1336 string nam =
e.nameStr();
1339 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1341 double startTheta = ns.attr<
double>(
e,
DD_CMU(startTheta));
1342 double deltaTheta = ns.attr<
double>(
e,
DD_CMU(deltaTheta));
1346 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1348 "+ Sphere: r_inner=%8.3f [cm] r_outer=%8.3f [cm]" 1349 " startPhi=%8.3f [rad] deltaPhi=%8.3f startTheta=%8.3f delteTheta=%8.3f [rad]",
1350 rinner / dd4hep::cm,
1351 router / dd4hep::cm,
1359 ns.addSolid(nam, Sphere(rinner, router, startTheta, deltaTheta, startPhi,
deltaPhi));
1364 void Converter<DDLTorus>::operator()(xml_h element)
const {
1366 xml_dim_t
e(element);
1367 string nam =
e.nameStr();
1368 double r = ns.attr<
double>(
e,
DD_CMU(torusRadius));
1371 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1376 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1378 "+ Torus: r=%10.3f [cm] r_inner=%10.3f [cm] r_outer=%10.3f [cm]" 1379 " startPhi=%10.3f [rad] deltaPhi=%10.3f [rad]",
1381 rinner / dd4hep::cm,
1382 router / dd4hep::cm,
1388 ns.addSolid(nam, Torus(
r, rinner, router, startPhi,
deltaPhi));
1393 void Converter<DDLPseudoTrap>::operator()(xml_h element)
const {
1395 xml_dim_t
e(element);
1396 string nam =
e.nameStr();
1397 double dx1 = ns.attr<
double>(
e,
DD_CMU(dx1));
1398 double dy1 = ns.attr<
double>(
e,
DD_CMU(dy1));
1399 double dx2 = ns.attr<
double>(
e,
DD_CMU(dx2));
1400 double dy2 = ns.attr<
double>(
e,
DD_CMU(dy2));
1401 double dz = ns.attr<
double>(
e, _U(
dz));
1402 double r = ns.attr<
double>(
e, _U(
radius));
1403 bool atMinusZ = ns.attr<
bool>(
e,
DD_CMU(atMinusZ));
1407 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1409 "+ Pseudotrap: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2=%.3f dy2=%.3f radius:%.3f atMinusZ:%s",
1420 ns.addSolid(nam, PseudoTrap(dx1, dx2, dy1, dy2,
dz,
r, atMinusZ));
1425 void Converter<DDLTrapezoid>::operator()(xml_h element)
const {
1427 xml_dim_t
e(element);
1428 string nam =
e.nameStr();
1429 double dz = ns.attr<
double>(
e, _U(
dz));
1430 double alp1 = ns.attr<
double>(
e,
DD_CMU(alp1));
1431 double bl1 = ns.attr<
double>(
e,
DD_CMU(bl1));
1432 double tl1 = ns.attr<
double>(
e,
DD_CMU(tl1));
1433 double h1 = ns.attr<
double>(
e,
DD_CMU(h1));
1434 double alp2 = ns.attr<
double>(
e,
DD_CMU(alp2));
1435 double bl2 = ns.attr<
double>(
e,
DD_CMU(bl2));
1436 double tl2 = ns.attr<
double>(
e,
DD_CMU(tl2));
1437 double h2 = ns.attr<
double>(
e,
DD_CMU(h2));
1438 double phi = ns.attr<
double>(
e, _U(
phi), 0.0);
1439 double theta = ns.attr<
double>(
e, _U(
theta), 0.0);
1443 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1445 "+ Trapezoid: dz=%10.3f [cm] alp1:%.3f bl1=%.3f tl1=%.3f alp2=%.3f bl2=%.3f tl2=%.3f h2=%.3f phi=%.3f " 1461 ns.addSolid(nam, Trap(
dz,
theta,
phi, h1, bl1, tl1, alp1, h2, bl2, tl2, alp2));
1466 void Converter<DDLTrd1>::operator()(xml_h element)
const {
1468 xml_dim_t
e(element);
1469 string nam =
e.nameStr();
1470 double dx1 = ns.attr<
double>(
e,
DD_CMU(dx1));
1471 double dy1 = ns.attr<
double>(
e,
DD_CMU(dy1));
1472 double dx2 = ns.attr<
double>(
e,
DD_CMU(dx2), 0.0);
1473 double dy2 = ns.attr<
double>(
e,
DD_CMU(dy2), dy1);
1478 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1480 "+ Trd1: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1489 ns.addSolid(nam, Trd1(dx1, dx2, dy1,
dz));
1493 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1495 "+ Trd1(which is actually Trd2): dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1504 ns.addSolid(nam, Trd2(dx1, dx2, dy1, dy2,
dz));
1510 void Converter<DDLTrd2>::operator()(xml_h element)
const {
1512 xml_dim_t
e(element);
1513 string nam =
e.nameStr();
1514 double dx1 = ns.attr<
double>(
e,
DD_CMU(dx1));
1515 double dy1 = ns.attr<
double>(
e,
DD_CMU(dy1));
1516 double dx2 = ns.attr<
double>(
e,
DD_CMU(dx2), 0.0);
1517 double dy2 = ns.attr<
double>(
e,
DD_CMU(dy2), dy1);
1522 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1524 "+ Trd1: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1533 ns.addSolid(nam, Trd2(dx1, dx2, dy1, dy2,
dz));
1538 void Converter<DDLTubs>::operator()(xml_h element)
const {
1540 xml_dim_t
e(element);
1541 string nam =
e.nameStr();
1545 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi), 0.0);
1550 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1552 "+ Tubs: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]" 1553 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]",
1562 ns.addSolid(nam, Tube(rmin, rmax,
dz, startPhi, startPhi +
deltaPhi));
1567 void Converter<DDLCutTubs>::operator()(xml_h element)
const {
1569 xml_dim_t
e(element);
1570 string nam =
e.nameStr();
1574 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1576 double lx = ns.attr<
double>(
e,
DD_CMU(lx));
1577 double ly = ns.attr<
double>(
e,
DD_CMU(ly));
1578 double lz = ns.attr<
double>(
e,
DD_CMU(lz));
1579 double tx = ns.attr<
double>(
e,
DD_CMU(tx));
1580 double ty = ns.attr<
double>(
e,
DD_CMU(ty));
1581 double tz = ns.attr<
double>(
e,
DD_CMU(tz));
1585 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1587 "+ CutTube: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]" 1588 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]...",
1597 ns.addSolid(nam, CutTube(rmin, rmax,
dz, startPhi, startPhi +
deltaPhi, lx, ly, lz, tx, ty, tz));
1602 void Converter<DDLTruncTubs>::operator()(xml_h element)
const {
1604 xml_dim_t
e(element);
1605 string nam =
e.nameStr();
1606 double zhalf = ns.attr<
double>(
e,
DD_CMU(zHalf));
1609 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1611 double cutAtStart = ns.attr<
double>(
e,
DD_CMU(cutAtStart));
1612 double cutAtDelta = ns.attr<
double>(
e,
DD_CMU(cutAtDelta));
1613 bool cutInside = ns.attr<
bool>(
e,
DD_CMU(cutInside));
1617 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1619 "+ TruncTube:zHalf=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]" 1620 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] atStart=%8.3f [cm] atDelta=%8.3f [cm] inside:%s",
1626 cutAtStart / dd4hep::cm,
1627 cutAtDelta / dd4hep::cm,
1632 ns.addSolid(nam, TruncatedTube(zhalf, rmin, rmax, startPhi,
deltaPhi, cutAtStart, cutAtDelta, cutInside));
1637 void Converter<DDLEllipticalTube>::operator()(xml_h element)
const {
1639 xml_dim_t
e(element);
1640 string nam =
e.nameStr();
1641 double dx = ns.attr<
double>(
e,
DD_CMU(xSemiAxis));
1642 double dy = ns.attr<
double>(
e,
DD_CMU(ySemiAxis));
1643 double dz = ns.attr<
double>(
e,
DD_CMU(zHeight));
1647 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1649 "+ EllipticalTube xSemiAxis=%8.3f [cm] ySemiAxis=%8.3f [cm] zHeight=%8.3f [cm]",
1656 ns.addSolid(nam, EllipticalTube(
dx,
dy,
dz));
1661 void Converter<DDLCone>::operator()(xml_h element)
const {
1663 xml_dim_t
e(element);
1664 string nam =
e.nameStr();
1666 double rmin1 = ns.attr<
double>(
e,
DD_CMU(rMin1));
1667 double rmin2 = ns.attr<
double>(
e,
DD_CMU(rMin2));
1668 double rmax1 = ns.attr<
double>(
e,
DD_CMU(rMax1));
1669 double rmax2 = ns.attr<
double>(
e,
DD_CMU(rMax2));
1670 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1676 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1678 "+ Cone: dz=%8.3f [cm]" 1679 " rmin1=%8.3f [cm] rmax1=%8.3f [cm]" 1680 " rmin2=%8.3f [cm] rmax2=%8.3f [cm]" 1681 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]",
1692 ns.addSolid(nam, ConeSegment(
dz, rmin1, rmax1, rmin2, rmax2, startPhi, phi2));
1697 void Converter<DDLShapeless>::operator()(xml_h element)
const {
1699 xml_dim_t
e(element);
1700 string nam =
e.nameStr();
1704 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1706 "+ Shapeless: THIS ONE CAN ONLY BE USED AT THE VOLUME LEVEL -> Shapeless: %s",
1711 ns.addSolid(nam, Box(1, 1, 1));
1716 void Converter<DDLAssembly>::operator()(xml_h element)
const {
1718 xml_dim_t
e(element);
1719 string nam =
e.nameStr();
1723 ns.context()->debug_shapes ? ALWAYS :
DEBUG,
"DD4CMS",
"+ Assembly: Adding solid -> Assembly: %s", nam.c_str());
1726 ns.addAssemblySolid(nam);
1731 void Converter<DDLBox>::operator()(xml_h element)
const {
1733 xml_dim_t
e(element);
1734 string nam =
e.nameStr();
1741 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1743 "+ Box: dx=%10.3f [cm] dy=%10.3f [cm] dz=%10.3f [cm]",
1750 ns.addSolid(nam, Box(
dx,
dy,
dz));
1755 void Converter<include_load>::operator()(xml_h element)
const {
1756 string fname = element.attr<
string>(_U(ref));
1759 doc = xml::DocumentHandler().load(
fp.fullPath());
1763 printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS :
DEBUG,
1765 "+++ Processing the CMS detector description %s",
1770 _option<DDRegistry>()->
includes.emplace_back(
doc);
1775 void Converter<include_unload>::operator()(xml_h element)
const {
1776 string fname = xml::DocumentHandler::system_path(element);
1777 xml::DocumentHolder(xml_elt_t(element).document()).assign(
nullptr);
1781 printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS :
DEBUG,
1783 "+++ Finished processing %s",
1790 void Converter<include_constants>::operator()(xml_h element)
const {
1802 enum class DDAxes {
x = 1, y = 2, z = 3, rho = 1, phi = 2, undefined };
1803 const std::map<std::string, DDAxes> axesmap{{
"x",
DDAxes::x},
1813 void Converter<DDLDivision>::operator()(xml_h element)
const {
1815 xml_dim_t
e(element);
1816 string childName =
e.nameStr();
1818 childName = ns.prepend(childName);
1822 parentName = ns.prepend(parentName);
1823 string axis = ns.attr<
string>(
e,
DD_CMU(axis));
1829 int nReplicas =
e.hasAttr(
DD_CMU(nReplicas)) ? ns.attr<
int>(
e,
DD_CMU(nReplicas)) : 0;
1833 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1835 "+++ Start executing Division of %s along %s (%d) with offset %6.3f and %6.3f to produce %s....",
1850 const TGeoTubeSeg* sh = (
const TGeoTubeSeg*)
shape;
1853 int numCopies = (
int)((sh->GetPhi2() - sh->GetPhi1()) / widthInDeg);
1857 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1859 "+++ ...divide %s along %s (%d) with offset %6.3f deg and %6.3f deg to produce %d copies",
1869 Volume child =
parent.divide(childName, static_cast<int>(axesmap.at(axis)), numCopies, startInDeg, widthInDeg);
1871 ns.context()->volumes[childName] =
child;
1875 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1877 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] is multivolume [%s]",
1880 parent.isValid() ?
"VALID" :
"INVALID",
1882 child.isValid() ?
"VALID" :
"INVALID",
1883 child->IsVolumeMulti() ?
"YES" :
"NO");
1887 double dy =
static_cast<const TGeoTrd1*
>(
shape)->GetDy();
1891 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1893 "+++ ...divide %s along %s (%d) with offset %6.3f cm and %6.3f cm to produce %d copies in %6.3f",
1906 ns.context()->volumes[childName] =
child;
1910 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1912 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] is multivolume [%s]",
1915 parent.isValid() ?
"VALID" :
"INVALID",
1917 child.isValid() ?
"VALID" :
"INVALID",
1918 child->IsVolumeMulti() ?
"YES" :
"NO");
1922 printout(
ERROR,
"DD4CMS",
"++ FAILED Division of a %s is not implemented yet!",
parent.solid().type());
1928 void Converter<DDLAlgorithm>::operator()(xml_h element)
const {
1930 xml_dim_t
e(element);
1931 string name =
e.nameStr();
1933 string type =
"DDCMS_" + ns.realName(
name);
1940 ns.context()->debug_algorithms ? ALWAYS :
DEBUG,
"DD4CMS",
"+++ Start executing algorithm %s....",
type.c_str());
1948 printout(ns.context()->debug_algorithms ? ALWAYS :
DEBUG,
1951 "+++ Executed algorithm: %08lX = %s",
1958 printout(
ERROR,
"DD4CMS",
"++ FAILED NOT ADDING SUBDETECTOR %08lX = %s",
ret,
name.c_str());
1961 template <
class InputIt,
class ForwardIt,
class BinOp>
1964 const auto pos = std::find_first_of(
first,
last, s_first, s_last);
1974 std::vector<string>
splitString(
const string&
str,
const string& delims =
",") {
1975 std::vector<string>
output;
1989 std::vector<double> splitNumeric(
const string&
str,
const string& delims =
",") {
1990 std::vector<double>
output;
2008 void Converter<DDLVector>::operator()(xml_h element)
const {
2012 xml_dim_t
e(element);
2013 string name = ns.prepend(
e.nameStr());
2014 string type = ns.attr<
string>(
e, _U(
type));
2015 string nEntries = ns.attr<
string>(
e,
DD_CMU(nEntries));
2016 string val =
e.text();
2017 val.erase(remove_if(
val.begin(),
val.end(), [](
unsigned char x) {
return isspace(x); }),
val.end());
2021 printout(ns.context()->debug_constants ? ALWAYS :
DEBUG,
2023 "+++ Vector<%s>: %s[%s]: %s",
2032 std::vector<double>
results = splitNumeric(
val);
2041 "++ Unresolved Vector<%s>: %s[%s]: %s. Try to resolve later. [%s]",
2056 void Converter<debug>::operator()(xml_h dbg)
const {
2058 if (dbg.hasChild(
DD_CMU(debug_constants)))
2059 ns.setContext()->debug_constants =
true;
2060 if (dbg.hasChild(
DD_CMU(debug_materials)))
2061 ns.setContext()->debug_materials =
true;
2062 if (dbg.hasChild(
DD_CMU(debug_rotations)))
2063 ns.setContext()->debug_rotations =
true;
2064 if (dbg.hasChild(
DD_CMU(debug_shapes)))
2065 ns.setContext()->debug_shapes =
true;
2066 if (dbg.hasChild(
DD_CMU(debug_volumes)))
2067 ns.setContext()->debug_volumes =
true;
2068 if (dbg.hasChild(
DD_CMU(debug_placements)))
2069 ns.setContext()->debug_placements =
true;
2070 if (dbg.hasChild(
DD_CMU(debug_namespaces)))
2071 ns.setContext()->debug_namespaces =
true;
2072 if (dbg.hasChild(
DD_CMU(debug_includes)))
2073 ns.setContext()->debug_includes =
true;
2074 if (dbg.hasChild(
DD_CMU(debug_algorithms)))
2075 ns.setContext()->debug_algorithms =
true;
2076 if (dbg.hasChild(
DD_CMU(debug_specpars)))
2077 ns.setContext()->debug_specpars =
true;
2081 void Converter<DDRegistry>::operator()(xml_h )
const {
2083 DDRegistry*
res = _option<DDRegistry>();
2091 "+++ RESOLVING %ld unknown constants..... (out of %ld)",
2092 res->unresolvedConst.size(),
2093 res->originalConst.size());
2096 while (!
res->unresolvedConst.empty()) {
2097 for (
auto&
i :
res->unresolvedConst) {
2098 const string&
n =
i.first;
2100 string&
v =
i.second;
2102 for (
idx =
v.find(
'[', 0);
idx != string::npos;
idx =
v.find(
'[',
idx + 1)) {
2103 idq =
v.find(
']',
idx + 1);
2105 auto r =
res->originalConst.find(
rep);
2106 if (r !=
res->originalConst.end()) {
2107 rep =
"(" + (*r).second +
")";
2111 if (
v.find(
']') == string::npos) {
2112 if (
v.find(
"-+") != string::npos ||
v.find(
"+-") != string::npos) {
2113 while ((
idx =
v.find(
"-+")) != string::npos)
2114 v.replace(
idx, 2,
"-");
2115 while ((
idx =
v.find(
"+-")) != string::npos)
2116 v.replace(
idx, 2,
"-");
2123 "+++ [%06ld] ---------- %-40s = %s",
2124 res->unresolvedConst.size() - 1,
2126 res->originalConst[
n].c_str());
2130 ns.addConstantNS(
n,
v,
"number");
2131 res->unresolvedConst.erase(
n);
2135 if (++
count > 10000)
2138 if (!
res->unresolvedConst.empty()) {
2139 for (
const auto&
e :
res->unresolvedConst)
2140 printout(
ERROR,
"DD4CMS",
"+++ Unresolved constant: %-40s = %s.",
e.first.c_str(),
e.second.c_str());
2141 except(
"DD4CMS",
"++ FAILED to resolve %ld constant entries:",
res->unresolvedConst.size());
2143 res->unresolvedConst.clear();
2144 res->originalConst.clear();
2148 void Converter<print_xml_doc>::operator()(xml_h element)
const {
2149 string fname = xml::DocumentHandler::system_path(element);
2153 printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS :
DEBUG,
2155 "+++ Processing data from: %s",
2163 xml_elt_t dddef(element);
2167 ns.addConstantNS(
"world_x",
"101*m",
"number");
2168 ns.addConstantNS(
"world_y",
"101*m",
"number");
2169 ns.addConstantNS(
"world_z",
"450*m",
"number");
2170 ns.addConstantNS(
"Air",
"materials:Air",
"string");
2171 ns.addConstantNS(
"Vacuum",
"materials:Vacuum",
"string");
2173 string fname = xml::DocumentHandler::system_path(element);
2174 bool open_geometry = dddef.hasChild(
DD_CMU(open_geometry)) ? dddef.child(
DD_CMU(open_geometry)) :
true;
2175 bool close_geometry = dddef.hasChild(
DD_CMU(close_geometry)) ? dddef.hasChild(
DD_CMU(close_geometry)) :
true;
2177 xml_coll_t(dddef, _U(
debug)).for_each(Converter<debug>(det, &
context));
2182 printout(
INFO,
"DD4CMS",
"+++ Processing the CMS detector description %s",
fname.c_str());
2185 Converter<print_xml_doc> print_doc(det, &
context);
2188 res.unresolvedConst.reserve(2000);
2189 res.originalConst.reserve(6000);
2190 print_doc((
doc = dddef.document()).
root());
2191 xml_coll_t(dddef,
DD_CMU(ConstantsSection)).for_each(Converter<ConstantsSection>(det, &
context, &
res));
2192 xml_coll_t(dddef,
DD_CMU(RotationSection)).for_each(Converter<RotationSection>(det, &
context));
2193 xml_coll_t(dddef,
DD_CMU(MaterialSection)).for_each(Converter<MaterialSection>(det, &
context));
2195 xml_coll_t(dddef,
DD_CMU(IncludeSection)).for_each(
DD_CMU(Include), Converter<include_load>(det, &
context, &
res));
2197 for (xml::Document
d :
res.includes) {
2199 Converter<include_constants>(det, &
context, &
res)((
doc =
d).root());
2202 Converter<DDRegistry>(det, &
context, &
res)(dddef);
2208 "+++ RESOLVING %ld Vectors.....",
2209 context.unresolvedVectors.size());
2211 while (!
context.unresolvedVectors.empty()) {
2212 for (
auto it =
context.unresolvedVectors.begin();
it !=
context.unresolvedVectors.end();) {
2213 std::vector<double>
result;
2214 for (
const auto&
i :
it->second) {
2215 result.emplace_back(dd4hep::_toDouble(
i));
2217 registry->insert({
it->first,
result});
2224 for (xml::Document
d :
res.includes) {
2226 xml_coll_t(
d.root(),
DD_CMU(MaterialSection)).for_each(Converter<MaterialSection>(det, &
context));
2228 if (open_geometry) {
2230 ns.addVolume(det.worldVolume());
2232 for (xml::Document
d :
res.includes) {
2234 xml_coll_t(
d.root(),
DD_CMU(RotationSection)).for_each(Converter<RotationSection>(det, &
context));
2236 for (xml::Document
d :
res.includes) {
2238 xml_coll_t(
d.root(),
DD_CMU(SolidSection)).for_each(Converter<SolidSection>(det, &
context));
2240 for (xml::Document
d :
res.includes) {
2242 xml_coll_t(
d.root(),
DD_CMU(LogicalPartSection)).for_each(Converter<LogicalPartSection>(det, &
context));
2244 for (xml::Document
d :
res.includes) {
2248 for (xml::Document
d :
res.includes) {
2250 xml_coll_t(
d.root(),
DD_CMU(PosPartSection)).for_each(Converter<PosPartSection>(det, &
context));
2252 for (xml::Document
d :
res.includes) {
2254 xml_coll_t(
d.root(),
DD_CMU(SpecParSection)).for_each(Converter<SpecParSection>(det, &
context));
2258 for (xml::Document
d :
res.includes)
2259 Converter<include_unload>(det, &
context, &
res)(
d.root());
2261 print_doc((
doc = dddef.document()).
root());
2263 xml_coll_t(dddef,
DD_CMU(SolidSection)).for_each(Converter<SolidSection>(det, &
context));
2270 while (!
context.unresolvedShapes.empty()) {
2271 for (
auto it =
context.unresolvedShapes.begin();
it !=
context.unresolvedShapes.end();) {
2272 auto const&
name =
it->first;
2273 auto const& aname = std::visit([](
auto&&
arg) ->
std::string {
return arg.firstSolidName; },
it->second);
2276 auto const& ait =
context.shapes.find(aname);
2277 if (ait->second.isValid()) {
2279 if (
bit->second.isValid()) {
2280 dd4hep::Solid
shape =
2281 std::visit([&ait, &
bit](
auto&&
arg) -> dd4hep::Solid {
return arg.make(ait->second,
bit->second); },
2292 xml_coll_t(dddef,
DD_CMU(LogicalPartSection)).for_each(Converter<LogicalPartSection>(det, &
context));
2294 xml_coll_t(dddef,
DD_CMU(PosPartSection)).for_each(Converter<PosPartSection>(det, &
context));
2295 xml_coll_t(dddef,
DD_CMU(SpecParSection)).for_each(Converter<SpecParSection>(det, &
context));
2297 printout(
ERROR,
"DD4CMS",
"Exception while processing xml source:%s",
doc.uri().c_str());
2298 printout(
ERROR,
"DD4CMS",
"----> %s",
e.what());
2303 if (close_geometry) {
2305 Volume geomv = ns.volume(
"cms:OCMS",
false);
2306 if (geomv.isValid())
2307 wv.placeVolume(geomv, 1);
2308 Volume mfv = ns.volume(
"cmsMagneticField:MAGF",
false);
2310 wv.placeVolume(mfv, 1);
2311 Volume mfv1 = ns.volume(
"MagneticFieldVolumes:MAGF",
false);
2313 wv.placeVolume(mfv1, 1);
2316 det.manager().CloseGeometry(
"nv");
2320 printout(
INFO,
"DDDefinition",
"+++ Finished processing %s",
fname.c_str());
2323 except(
"DDDefinition",
"+++ FAILED to process unknown DOM tree [Invalid Handle]");
DDLPosPart handles PosPart elements.
DDLSphere processes all Sphere elements.
DDLDivision processes Division elements.
std::unordered_map< std::string, std::variant< BooleanShape< dd4hep::UnionSolid >, BooleanShape< dd4hep::SubtractionSolid >, BooleanShape< dd4hep::IntersectionSolid > > > unresolvedShapes
const bool isValid(const Frame &aFrame, const FrameQuality &aQuality, const uint16_t aExpectedPos)
static void placeAssembly(Volume *parentPtr, const string &parentName, Volume *childPtr, const string &childName, int copy, const Transform3D &transform, cms::DDNamespace &ns)
ROOT::Math::Plane3D::Vector Vector
DDLVector handles Rotation and ReflectionRotation elements.
ret
prodAgent to be discontinued
constexpr NumType convertRadToDeg(NumType radians)
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > Translation
DDLSpecPar processes SpecPar elements.
DDParsingContext *const context() const
DDLEllipticalTube processes all EllipticalTube elements.
TGeoCombiTrans * createPlacement(const Rotation3D &iRot, const Position &iTrans)
std::vector< std::string > splitString(const std::string &fLine)
DDLAlgorithm processes Algorithm elements.
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
DDRotationMatrix makeRotation3D(double thetaX, double phiX, double thetaY, double phiY, double thetaZ, double phiZ)
std::unordered_map< std::string, std::vector< double > > DDVectorsMap
std::unordered_map< std::string, std::string > unresolvedConst
static const std::string & rotName(const T &rot, const cms::DDParsingContext &context)
U second(std::pair< T, U > const &p)
DDLBox processes Box elements.
DDLElementaryMaterial processes ElementaryMaterial elements.
DDLAssembly processes Assembly elements.
static constexpr long s_executed
DDLCone processes all Cone elements.
dd4hep::PlacedVolume PlacedVolume
DDRotationMatrix makeRotReflect(double thetaX, double phiX, double thetaY, double phiY, double thetaZ, double phiZ)
Abs< T >::type abs(const T &t)
constexpr unsigned int hash(const char *str, int h=0)
std::unordered_map< std::string, dd4hep::Solid > shapes
static void convert_boolean(cms::DDParsingContext *context, xml_h element)
dd4hep::Solid solid(const std::string &name) const
Namespace of DDCMS conversion namespace.
DDLTubs processes Tubs elements.
DDLLogicalPart processes LogicalPart elements.
DDLRotationByAxis handles RotationByAxis elements.
DDLCompositeMaterial processes all CompositeMaterial elements.
std::vector< xml::Document > includes
static long load_dddefinition(Detector &det, xml_h element)
Converter for <DDDefinition> tags.
DDAxes
analagous to geant4/source/global/HEPGeometry/include/geomdefs.hh
std::unordered_map< std::string, std::string > originalConst
dd4hep::Solid addSolid(const std::string &name, dd4hep::Solid solid) const
DDLRotationSequence handles a set of Rotations.
void for_each_token(InputIt first, InputIt last, ForwardIt s_first, ForwardIt s_last, BinOp binary_op)
SOARotation< float > Rotation
T angle(T x1, T y1, T z1, T x2, T y2, T z2)
dd4hep::Assembly assembly(const std::string &name, bool exception=true) const