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) {
593 const char* matname = nam.c_str();
595 xml_coll_t composites(xmat,
DD_CMU(MaterialFraction));
596 TGeoMixture*
mix =
new TGeoMixture(nam.c_str(), composites.size(),
density);
600 printout(ns.context()->debug_materials ? ALWAYS :
DEBUG,
602 "++ Converting material %-48s Density: %8.3f [g/cm3] ROOT: %8.3f [g/cm3]",
603 (
'"' + nam +
'"').c_str(),
609 if (ns.context()->makePayload) {
610 ns.context()->compMaterialsVec.emplace_back(std::make_pair(nam,
density));
612 for (composites.reset(); composites; ++composites) {
613 xml_dim_t xfrac(composites);
614 xml_dim_t xfrac_mat(xfrac.child(
DD_CMU(rMaterial)));
616 string fracname = ns.realName(xfrac_mat.nameStr());
618 if (ns.context()->makePayload) {
619 ns.context()->compMaterialsRefs[nam].emplace_back(
622 TGeoMaterial* frac_mat = mgr.GetMaterial(fracname.c_str());
623 if (frac_mat ==
nullptr)
624 frac_mat = mgr.GetMaterial(ns.prepend(fracname).c_str());
630 throw cms::Exception(
"DD4CMS") <<
"Composite material \"" + fracname +
"\" or \"" + ns.prepend(fracname) +
631 "\" not yet defined.";
633 mix->SetTemperature(ns.context()->description.stdConditions().temperature);
634 mix->SetPressure(ns.context()->description.stdConditions().pressure);
637 TGeoMedium* medium = mgr.GetMedium(matname);
638 if (
nullptr == medium) {
640 medium =
new TGeoMedium(matname, unique_mat_id,
mix);
641 medium->SetTitle(
"material");
642 medium->SetUniqueID(unique_mat_id);
649 void Converter<DDLRotation>::operator()(xml_h element)
const {
652 xml_dim_t xrot(element);
653 string nam = xrot.nameStr();
655 double phiX = xrot.hasAttr(
DD_CMU(phiX)) ? ns.attr<
double>(xrot,
DD_CMU(phiX)) : 0e0;
657 double phiY = xrot.hasAttr(
DD_CMU(phiY)) ? ns.attr<
double>(xrot,
DD_CMU(phiY)) : 0e0;
659 double phiZ = xrot.hasAttr(
DD_CMU(phiZ)) ? ns.attr<
double>(xrot,
DD_CMU(phiZ)) : 0e0;
666 "+++ Adding rotation: %-32s: (theta/phi)[rad] X: %6.3f %6.3f Y: %6.3f %6.3f Z: %6.3f %6.3f",
667 ns.prepend(nam).c_str(),
677 ns.addRotation(nam,
rot);
682 void Converter<DDLReflectionRotation>::operator()(xml_h element)
const {
685 xml_dim_t xrot(element);
686 string name = xrot.nameStr();
688 double phiX = xrot.hasAttr(
DD_CMU(phiX)) ? ns.attr<
double>(xrot,
DD_CMU(phiX)) : 0e0;
690 double phiY = xrot.hasAttr(
DD_CMU(phiY)) ? ns.attr<
double>(xrot,
DD_CMU(phiY)) : 0e0;
692 double phiZ = xrot.hasAttr(
DD_CMU(phiZ)) ? ns.attr<
double>(xrot,
DD_CMU(phiZ)) : 0e0;
698 "+++ Adding reflection rotation: %-32s: (theta/phi)[rad] X: %6.3f %6.3f Y: %6.3f %6.3f Z: %6.3f %6.3f",
699 ns.prepend(
name).c_str(),
715 void Converter<DDLRotationSequence>::operator()(xml_h element)
const {
718 xml_dim_t xrot(element);
719 string nam = xrot.nameStr();
721 xml_coll_t rotations(xrot,
DD_CMU(RotationByAxis));
722 for (rotations.reset(); rotations; ++rotations) {
723 string axis = ns.attr<
string>(rotations,
DD_CMU(axis));
724 double angle = ns.attr<
double>(rotations, _U(
angle));
731 "+ Adding rotation to: %-29s: (axis/angle)[rad] Axis: %s Angle: %6.3f",
747 "+++ Adding rotation sequence: %-23s: %6.3f %6.3f %6.3f, %6.3f %6.3f %6.3f, %6.3f %6.3f %6.3f",
748 ns.prepend(nam).c_str(),
761 ns.addRotation(nam,
rot);
766 void Converter<DDLRotationByAxis>::operator()(xml_h element)
const {
769 xml_dim_t xrot(element);
770 xml_dim_t par(xrot.parent());
771 if (xrot.hasAttr(_U(
name))) {
772 string nam = xrot.nameStr();
773 string axis = ns.attr<
string>(xrot,
DD_CMU(axis));
774 double angle = ns.attr<
double>(xrot, _U(
angle));
782 "+++ Adding rotation: %-32s: (axis/angle)[rad] Axis: %s Angle: %6.3f",
783 ns.prepend(nam).c_str(),
789 ns.addRotation(nam,
rot);
795 void Converter<DDLLogicalPart>::operator()(xml_h element)
const {
797 xml_dim_t
e(element);
799 string mat =
e.child(
DD_CMU(rMaterial)).attr<
string>(_U(
name));
800 string volName = ns.prepend(
e.attr<
string>(_U(
name)));
801 Solid solid = ns.solid(
sol);
802 Material material = ns.material(mat);
803 if (ns.context()->assemblySolids.count(
sol) == 1) {
807 ns.addAssembly(volName,
false);
815 ns.addVolume(
Volume(volName, solid, material));
819 printout(ns.context()->debug_volumes ? ALWAYS :
DEBUG,
821 "+++ %s Volume: %-24s [%s] Shape: %-32s [%s] Material: %-40s [%s]",
824 volume.isValid() ?
"VALID" :
"INVALID",
826 solid.isValid() ?
"VALID" :
"INVALID",
828 material.isValid() ?
"VALID" :
"INVALID");
835 void Converter<DDLTransform3D>::operator()(xml_h element)
const {
837 Transform3D* tr = _option<Transform3D>();
838 xml_dim_t
e(element);
841 xml_dim_t refRotation =
e.child(
DD_CMU(rRotation),
false);
842 xml_dim_t refReflectionRotation =
e.child(
DD_CMU(rReflectionRotation),
false);
846 if (translation.ptr()) {
847 double x = ns.attr<
double>(translation, _U(
x));
848 double y = ns.attr<
double>(translation, _U(
y));
849 double z = ns.attr<
double>(translation, _U(
z));
856 rot = RotationZYX(
z,
y,
x);
857 }
else if (refRotation.ptr()) {
858 string rotName = ns.prepend(refRotation.nameStr());
860 }
else if (refReflectionRotation.ptr()) {
861 string rotName = ns.prepend(refReflectionRotation.nameStr());
864 *tr = Transform3D(
rot,
pos);
868 const string& parentName,
870 const string& childName,
878 "+++ Parent vol: %-24s Child: %-32s, copy:%d",
885 TGeoShape*
shape = (*childPtr)->GetShape();
888 TGeoShapeAssembly* as = (TGeoShapeAssembly*)
shape;
892 as->NeedsBBoxRecompute();
898 TString nam_id = TString::Format(
"%s_%d", (*childPtr)->GetName(),
copy);
899 n =
static_cast<TGeoNode*
>((*parentPtr)->GetNode(nam_id));
901 printout(
ERROR,
"PlacedVolume",
"++ Attempt to add already existing node %s", (
const char*)nam_id);
907 if ((*childPtr)->IsAssembly()) {
914 printout(
ERROR,
"DD4CMS",
"+++ Placement FAILED! Parent:%s Child:%s", parentName.c_str(), childName.c_str());
920 void Converter<DDLPosPart>::operator()(xml_h element)
const {
922 xml_dim_t
e(element);
924 string parentName = ns.prepend(ns.attr<
string>(
e.child(
DD_CMU(rParent)), _U(
name)));
925 string childName = ns.prepend(ns.attr<
string>(
e.child(
DD_CMU(rChild)), _U(
name)));
931 Assembly parAsmb = ns.assembly(parentName,
false);
932 Assembly childAsmb = ns.assembly(childName,
false);
936 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
938 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] copy:%d",
941 parent.isValid() ?
"VALID" :
"INVALID",
943 child.isValid() ?
"VALID" :
"INVALID",
948 if (!
parent.isValid() && !parAsmb.isValid() && strchr(parentName.c_str(),
NAMESPACE_SEP) ==
nullptr) {
949 parentName = ns.prepend(parentName);
950 parAsmb = ns.assembly(parentName,
false);
951 if (!parAsmb.isValid())
952 parent = ns.volume(parentName);
955 if (!
child.isValid() && !childAsmb.isValid() && strchr(childName.c_str(),
NAMESPACE_SEP) ==
nullptr) {
956 childName = ns.prepend(childName);
957 child = ns.volume(childName,
false);
958 childAsmb = ns.assembly(childName,
false);
960 if (parAsmb.isValid() || childAsmb.isValid()) {
961 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
963 "***** Placing assembly parent %s, child %s",
966 Volume* parentPtr = parAsmb.isValid() ? &parAsmb : &
parent;
967 Volume* childPtr = childAsmb.isValid() ? &childAsmb : &
child;
974 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
976 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] copy:%d",
979 parent.isValid() ?
"VALID" :
"INVALID",
981 child.isValid() ?
"VALID" :
"INVALID",
987 if (
child.isValid()) {
992 except(
"dd4hep",
"Volume: Attempt to assign daughters to an invalid physical parent volume.");
995 except(
"dd4hep",
"Volume: Attempt to assign an invalid physical daughter volume.");
1000 TGeoShapeAssembly* as = (TGeoShapeAssembly*)
shape;
1004 as->NeedsBBoxRecompute();
1009 TString nam_id = TString::Format(
"%s_%d",
child->GetName(),
copy);
1010 if (ns.context()->validate) {
1011 n =
static_cast<TGeoNode*
>(
parent->GetNode(nam_id));
1013 printout(
ERROR,
"PlacedVolume",
"++ Attempt to add already existing node %s", (
const char*)nam_id);
1018 Translation3D trans(
transform.Translation());
1020 trans.GetComponents(
x,
y,
z);
1024 n =
static_cast<TGeoNode*
>(
parent->GetNodes()->Last());
1025 assert(
n->GetName() == nam_id);
1026 n->TGeoNode::SetUserExtension(
new PlacedVolume::Object());
1029 if (!
pv.isValid()) {
1032 "+++ Placement FAILED! Parent:%s Child:%s Valid:%s",
1035 yes_no(
child.isValid()));
1041 void Converter<PartSelector>::operator()(xml_h element)
const {
1044 dd4hep::SpecParRegistry& registry = *
context->description.extension<dd4hep::SpecParRegistry>();
1045 xml_dim_t
e(element);
1046 xml_dim_t specPar =
e.parent();
1047 string specParName = specPar.attr<
string>(_U(
name));
1052 printout(ns.context()->debug_specpars ? ALWAYS :
DEBUG,
1054 "+++ PartSelector for %s path: %s",
1055 specParName.c_str(),
1060 size_t pos = std::string::npos;
1061 if ((
pos =
path.find(
"//.*:")) != std::string::npos) {
1064 registry.specpars[specParName].paths.emplace_back(
std::move(
path));
1069 void Converter<Parameter>::operator()(xml_h element)
const {
1072 dd4hep::SpecParRegistry& registry = *
context->description.extension<dd4hep::SpecParRegistry>();
1073 xml_dim_t
e(element);
1074 xml_dim_t specPar =
e.parent();
1075 xml_dim_t specParSect = specPar.parent();
1076 string specParName = specPar.attr<
string>(_U(
name));
1077 string name =
e.nameStr();
1079 bool eval = specParSect.hasAttr(_U(eval)) ? specParSect.attr<
bool>(_U(eval)) :
false;
1080 eval = specPar.hasAttr(_U(eval)) ? specPar.attr<
bool>(_U(eval)) : eval;
1081 eval =
e.hasAttr(_U(eval)) ?
e.attr<
bool>(_U(eval)) : eval;
1083 string type = eval ?
"number" :
"string";
1087 printout(ns.context()->debug_specpars ? ALWAYS :
DEBUG,
1089 "+++ Parameter for %s: %s value %s is a %s",
1090 specParName.c_str(),
1098 if (
idx == string::npos &&
type ==
"number") {
1099 registry.specpars[specParName].numpars[
name].emplace_back(dd4hep::_toDouble(
value));
1102 if (
idx == string::npos ||
type ==
"string") {
1107 while (
idx != string::npos) {
1111 if (idp == string::npos || idp > idq)
1113 else if (idp != string::npos && idp < idq)
1121 for (
idx =
v.find(
'[', 0);
idx != string::npos;
idx =
v.find(
'[',
idx + 1)) {
1122 idq =
v.find(
']',
idx + 1);
1124 auto r = ns.context()->description.constants().find(
rep);
1125 if (
r != ns.context()->description.constants().end()) {
1126 rep =
"(" +
r->second->type +
")";
1130 registry.specpars[specParName].numpars[
name].emplace_back(dd4hep::_toDouble(
value));
1133 template <
typename TYPE>
1136 xml_dim_t
e(element);
1137 string nam =
e.nameStr();
1138 string solidName[2];
1142 if (
e.hasChild(
DD_CMU(rSolid))) {
1143 for (xml_coll_t
c(element,
DD_CMU(rSolid)); cnt < 2 &&
c; ++
c, ++cnt) {
1144 solidName[cnt] =
c.attr<
string>(_U(
name));
1145 solids[cnt] = ns.
solid(
c.attr<
string>(_U(
name)));
1148 solidName[0] =
e.attr<
string>(
DD_CMU(firstSolid));
1151 solidName[1] =
e.attr<
string>(
DD_CMU(secondSolid));
1156 except(
"DD4CMS",
"+++ Failed to create boolean solid %s. Found only %d parts.", nam.c_str(), cnt);
1163 "+++ BooleanSolid: %s Left: %-32s Right: %-32s",
1165 ((solids[0].ptr() ==
nullptr) ? solidName[0].c_str() : solids[0]->GetName()),
1166 ((solids[1].ptr() ==
nullptr) ? solidName[1].c_str() : solids[1]->GetName()));
1172 Converter<DDLTransform3D>(
context->description,
context, &trafo)(element);
1173 boolean =
TYPE(solids[0], solids[1], trafo);
1177 Converter<DDLTransform3D>(
context->description,
context, &trafo)(element);
1180 if (solids[0].
isValid() ==
false) {
1181 printout(
ERROR,
"DD4CMS",
"++ Solid not defined yet: %s", solidName[0].c_str());
1183 if (solids[1].
isValid() ==
false) {
1184 printout(
ERROR,
"DD4CMS",
"++ Solid not defined yet: %s", solidName[1].c_str());
1186 printout(
ERROR,
"DD4CMS",
"++ Re-order XML files to prevent references to undefined solids");
1197 void Converter<DDLUnionSolid>::operator()(xml_h element)
const {
1198 convert_boolean<UnionSolid>(_param<cms::DDParsingContext>(), element);
1203 void Converter<DDLSubtractionSolid>::operator()(xml_h element)
const {
1204 convert_boolean<SubtractionSolid>(_param<cms::DDParsingContext>(), element);
1209 void Converter<DDLIntersectionSolid>::operator()(xml_h element)
const {
1210 convert_boolean<IntersectionSolid>(_param<cms::DDParsingContext>(), element);
1215 void Converter<DDLPolycone>::operator()(xml_h element)
const {
1217 xml_dim_t
e(element);
1218 string nam =
e.nameStr();
1219 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1221 vector<double>
z, rmin, rmax,
r;
1223 for (xml_coll_t rzpoint(element,
DD_CMU(RZPoint)); rzpoint; ++rzpoint) {
1224 z.emplace_back(ns.attr<
double>(rzpoint, _U(
z)));
1225 r.emplace_back(ns.attr<
double>(rzpoint, _U(
r)));
1228 for (xml_coll_t zplane(element,
DD_CMU(ZSection)); zplane; ++zplane) {
1229 rmin.emplace_back(ns.attr<
double>(zplane,
DD_CMU(
rMin)));
1230 rmax.emplace_back(ns.attr<
double>(zplane,
DD_CMU(
rMax)));
1231 z.emplace_back(ns.attr<
double>(zplane, _U(
z)));
1236 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1238 "+ Polycone: startPhi=%10.3f [rad] deltaPhi=%10.3f [rad] %4ld z-planes",
1245 ns.addSolid(nam, Polycone(startPhi,
deltaPhi, rmin, rmax,
z));
1249 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1251 "+ Polycone: startPhi=%10.3f [rad] deltaPhi=%10.3f [rad] %4ld z-planes and %4ld radii",
1259 ns.addSolid(nam, Polycone(startPhi,
deltaPhi,
r,
z));
1265 void Converter<DDLExtrudedPolygon>::operator()(xml_h element)
const {
1267 xml_dim_t
e(element);
1268 string nam =
e.nameStr();
1269 vector<double> pt_x, pt_y, sec_x, sec_y, sec_z, sec_scale;
1272 sec_z.emplace_back(ns.attr<
double>(
sec, _U(
z)));
1273 sec_x.emplace_back(ns.attr<
double>(
sec, _U(
x)));
1274 sec_y.emplace_back(ns.attr<
double>(
sec, _U(
y)));
1275 sec_scale.emplace_back(ns.attr<
double>(
sec,
DD_CMU(
scale), 1.0));
1277 for (xml_coll_t
pt(element,
DD_CMU(XYPoint));
pt; ++
pt) {
1278 pt_x.emplace_back(ns.attr<
double>(
pt, _U(
x)));
1279 pt_y.emplace_back(ns.attr<
double>(
pt, _U(
y)));
1284 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1286 "+ ExtrudedPolygon: %4ld points %4ld zxy sections",
1292 ns.addSolid(nam,
ExtrudedPolygon(pt_x, pt_y, sec_z, sec_x, sec_y, sec_scale));
1297 void Converter<DDLPolyhedra>::operator()(xml_h element)
const {
1299 xml_dim_t
e(element);
1300 string nam =
e.nameStr();
1301 double numSide = ns.attr<
int>(
e,
DD_CMU(numSide));
1302 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1304 vector<double>
z, rmin, rmax;
1306 for (xml_coll_t zplane(element,
DD_CMU(RZPoint)); zplane; ++zplane) {
1307 rmin.emplace_back(0.0);
1308 rmax.emplace_back(ns.attr<
double>(zplane, _U(
r)));
1309 z.emplace_back(ns.attr<
double>(zplane, _U(
z)));
1311 for (xml_coll_t zplane(element,
DD_CMU(ZSection)); zplane; ++zplane) {
1312 rmin.emplace_back(ns.attr<
double>(zplane,
DD_CMU(
rMin)));
1313 rmax.emplace_back(ns.attr<
double>(zplane,
DD_CMU(
rMax)));
1314 z.emplace_back(ns.attr<
double>(zplane, _U(
z)));
1319 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1321 "+ Polyhedra:startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] %4d sides %4ld z-planes",
1334 void Converter<DDLSphere>::operator()(xml_h element)
const {
1336 xml_dim_t
e(element);
1337 string nam =
e.nameStr();
1340 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1342 double startTheta = ns.attr<
double>(
e,
DD_CMU(startTheta));
1343 double deltaTheta = ns.attr<
double>(
e,
DD_CMU(deltaTheta));
1347 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1349 "+ Sphere: r_inner=%8.3f [cm] r_outer=%8.3f [cm]" 1350 " startPhi=%8.3f [rad] deltaPhi=%8.3f startTheta=%8.3f delteTheta=%8.3f [rad]",
1351 rinner / dd4hep::cm,
1352 router / dd4hep::cm,
1360 ns.addSolid(nam, Sphere(rinner, router, startTheta, deltaTheta, startPhi,
deltaPhi));
1365 void Converter<DDLTorus>::operator()(xml_h element)
const {
1367 xml_dim_t
e(element);
1368 string nam =
e.nameStr();
1369 double r = ns.attr<
double>(
e,
DD_CMU(torusRadius));
1372 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1377 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1379 "+ Torus: r=%10.3f [cm] r_inner=%10.3f [cm] r_outer=%10.3f [cm]" 1380 " startPhi=%10.3f [rad] deltaPhi=%10.3f [rad]",
1382 rinner / dd4hep::cm,
1383 router / dd4hep::cm,
1389 ns.addSolid(nam, Torus(
r, rinner, router, startPhi,
deltaPhi));
1394 void Converter<DDLPseudoTrap>::operator()(xml_h element)
const {
1396 xml_dim_t
e(element);
1397 string nam =
e.nameStr();
1398 double dx1 = ns.attr<
double>(
e,
DD_CMU(dx1));
1399 double dy1 = ns.attr<
double>(
e,
DD_CMU(dy1));
1400 double dx2 = ns.attr<
double>(
e,
DD_CMU(dx2));
1401 double dy2 = ns.attr<
double>(
e,
DD_CMU(dy2));
1402 double dz = ns.attr<
double>(
e, _U(
dz));
1403 double r = ns.attr<
double>(
e, _U(
radius));
1404 bool atMinusZ = ns.attr<
bool>(
e,
DD_CMU(atMinusZ));
1408 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1410 "+ Pseudotrap: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2=%.3f dy2=%.3f radius:%.3f atMinusZ:%s",
1421 ns.addSolid(nam, PseudoTrap(dx1, dx2, dy1, dy2,
dz,
r, atMinusZ));
1426 void Converter<DDLTrapezoid>::operator()(xml_h element)
const {
1428 xml_dim_t
e(element);
1429 string nam =
e.nameStr();
1430 double dz = ns.attr<
double>(
e, _U(
dz));
1431 double alp1 = ns.attr<
double>(
e,
DD_CMU(alp1));
1432 double bl1 = ns.attr<
double>(
e,
DD_CMU(bl1));
1433 double tl1 = ns.attr<
double>(
e,
DD_CMU(tl1));
1434 double h1 = ns.attr<
double>(
e,
DD_CMU(h1));
1435 double alp2 = ns.attr<
double>(
e,
DD_CMU(alp2));
1436 double bl2 = ns.attr<
double>(
e,
DD_CMU(bl2));
1437 double tl2 = ns.attr<
double>(
e,
DD_CMU(tl2));
1438 double h2 = ns.attr<
double>(
e,
DD_CMU(h2));
1439 double phi = ns.attr<
double>(
e, _U(
phi), 0.0);
1440 double theta = ns.attr<
double>(
e, _U(
theta), 0.0);
1444 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1446 "+ Trapezoid: dz=%10.3f [cm] alp1:%.3f bl1=%.3f tl1=%.3f alp2=%.3f bl2=%.3f tl2=%.3f h2=%.3f phi=%.3f " 1462 ns.addSolid(nam, Trap(
dz,
theta,
phi, h1, bl1, tl1, alp1, h2, bl2, tl2, alp2));
1467 void Converter<DDLTrd1>::operator()(xml_h element)
const {
1469 xml_dim_t
e(element);
1470 string nam =
e.nameStr();
1471 double dx1 = ns.attr<
double>(
e,
DD_CMU(dx1));
1472 double dy1 = ns.attr<
double>(
e,
DD_CMU(dy1));
1473 double dx2 = ns.attr<
double>(
e,
DD_CMU(dx2), 0.0);
1474 double dy2 = ns.attr<
double>(
e,
DD_CMU(dy2), dy1);
1479 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1481 "+ Trd1: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1490 ns.addSolid(nam, Trd1(dx1, dx2, dy1,
dz));
1494 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1496 "+ Trd1(which is actually Trd2): dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1505 ns.addSolid(nam, Trd2(dx1, dx2, dy1, dy2,
dz));
1511 void Converter<DDLTrd2>::operator()(xml_h element)
const {
1513 xml_dim_t
e(element);
1514 string nam =
e.nameStr();
1515 double dx1 = ns.attr<
double>(
e,
DD_CMU(dx1));
1516 double dy1 = ns.attr<
double>(
e,
DD_CMU(dy1));
1517 double dx2 = ns.attr<
double>(
e,
DD_CMU(dx2), 0.0);
1518 double dy2 = ns.attr<
double>(
e,
DD_CMU(dy2), dy1);
1523 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1525 "+ Trd1: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
1534 ns.addSolid(nam, Trd2(dx1, dx2, dy1, dy2,
dz));
1539 void Converter<DDLTubs>::operator()(xml_h element)
const {
1541 xml_dim_t
e(element);
1542 string nam =
e.nameStr();
1546 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi), 0.0);
1551 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1553 "+ Tubs: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]" 1554 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]",
1563 ns.addSolid(nam, Tube(rmin, rmax,
dz, startPhi, startPhi +
deltaPhi));
1568 void Converter<DDLCutTubs>::operator()(xml_h element)
const {
1570 xml_dim_t
e(element);
1571 string nam =
e.nameStr();
1575 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1577 double lx = ns.attr<
double>(
e,
DD_CMU(lx));
1578 double ly = ns.attr<
double>(
e,
DD_CMU(ly));
1579 double lz = ns.attr<
double>(
e,
DD_CMU(lz));
1580 double tx = ns.attr<
double>(
e,
DD_CMU(tx));
1581 double ty = ns.attr<
double>(
e,
DD_CMU(ty));
1582 double tz = ns.attr<
double>(
e,
DD_CMU(tz));
1586 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1588 "+ CutTube: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]" 1589 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]...",
1598 ns.addSolid(nam, CutTube(rmin, rmax,
dz, startPhi, startPhi +
deltaPhi, lx, ly, lz, tx, ty, tz));
1603 void Converter<DDLTruncTubs>::operator()(xml_h element)
const {
1605 xml_dim_t
e(element);
1606 string nam =
e.nameStr();
1607 double zhalf = ns.attr<
double>(
e,
DD_CMU(zHalf));
1610 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1612 double cutAtStart = ns.attr<
double>(
e,
DD_CMU(cutAtStart));
1613 double cutAtDelta = ns.attr<
double>(
e,
DD_CMU(cutAtDelta));
1614 bool cutInside = ns.attr<
bool>(
e,
DD_CMU(cutInside));
1618 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1620 "+ TruncTube:zHalf=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]" 1621 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] atStart=%8.3f [cm] atDelta=%8.3f [cm] inside:%s",
1627 cutAtStart / dd4hep::cm,
1628 cutAtDelta / dd4hep::cm,
1633 ns.addSolid(nam, TruncatedTube(zhalf, rmin, rmax, startPhi,
deltaPhi, cutAtStart, cutAtDelta, cutInside));
1638 void Converter<DDLEllipticalTube>::operator()(xml_h element)
const {
1640 xml_dim_t
e(element);
1641 string nam =
e.nameStr();
1642 double dx = ns.attr<
double>(
e,
DD_CMU(xSemiAxis));
1643 double dy = ns.attr<
double>(
e,
DD_CMU(ySemiAxis));
1644 double dz = ns.attr<
double>(
e,
DD_CMU(zHeight));
1648 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1650 "+ EllipticalTube xSemiAxis=%8.3f [cm] ySemiAxis=%8.3f [cm] zHeight=%8.3f [cm]",
1657 ns.addSolid(nam, EllipticalTube(
dx,
dy,
dz));
1662 void Converter<DDLCone>::operator()(xml_h element)
const {
1664 xml_dim_t
e(element);
1665 string nam =
e.nameStr();
1667 double rmin1 = ns.attr<
double>(
e,
DD_CMU(rMin1));
1668 double rmin2 = ns.attr<
double>(
e,
DD_CMU(rMin2));
1669 double rmax1 = ns.attr<
double>(
e,
DD_CMU(rMax1));
1670 double rmax2 = ns.attr<
double>(
e,
DD_CMU(rMax2));
1671 double startPhi = ns.attr<
double>(
e,
DD_CMU(startPhi));
1677 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1679 "+ Cone: dz=%8.3f [cm]" 1680 " rmin1=%8.3f [cm] rmax1=%8.3f [cm]" 1681 " rmin2=%8.3f [cm] rmax2=%8.3f [cm]" 1682 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]",
1693 ns.addSolid(nam, ConeSegment(
dz, rmin1, rmax1, rmin2, rmax2, startPhi, phi2));
1698 void Converter<DDLShapeless>::operator()(xml_h element)
const {
1700 xml_dim_t
e(element);
1701 string nam =
e.nameStr();
1705 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1707 "+ Shapeless: THIS ONE CAN ONLY BE USED AT THE VOLUME LEVEL -> Shapeless: %s",
1712 ns.addSolid(nam, Box(1, 1, 1));
1717 void Converter<DDLAssembly>::operator()(xml_h element)
const {
1719 xml_dim_t
e(element);
1720 string nam =
e.nameStr();
1724 ns.context()->debug_shapes ? ALWAYS :
DEBUG,
"DD4CMS",
"+ Assembly: Adding solid -> Assembly: %s", nam.c_str());
1727 ns.addAssemblySolid(nam);
1732 void Converter<DDLBox>::operator()(xml_h element)
const {
1734 xml_dim_t
e(element);
1735 string nam =
e.nameStr();
1742 printout(ns.context()->debug_shapes ? ALWAYS :
DEBUG,
1744 "+ Box: dx=%10.3f [cm] dy=%10.3f [cm] dz=%10.3f [cm]",
1751 ns.addSolid(nam, Box(
dx,
dy,
dz));
1756 void Converter<include_load>::operator()(xml_h element)
const {
1757 string fname = element.attr<
string>(_U(ref));
1760 doc = xml::DocumentHandler().load(
fp.fullPath());
1764 printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS :
DEBUG,
1766 "+++ Processing the CMS detector description %s",
1771 _option<DDRegistry>()->
includes.emplace_back(
doc);
1776 void Converter<include_unload>::operator()(xml_h element)
const {
1777 string fname = xml::DocumentHandler::system_path(element);
1778 xml::DocumentHolder(xml_elt_t(element).document()).assign(
nullptr);
1782 printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS :
DEBUG,
1784 "+++ Finished processing %s",
1791 void Converter<include_constants>::operator()(xml_h element)
const {
1803 enum class DDAxes {
x = 1, y = 2, z = 3, rho = 1, phi = 2, undefined };
1804 const std::map<std::string, DDAxes> axesmap{{
"x",
DDAxes::x},
1814 void Converter<DDLDivision>::operator()(xml_h element)
const {
1816 xml_dim_t
e(element);
1817 string childName =
e.nameStr();
1819 childName = ns.prepend(childName);
1823 parentName = ns.prepend(parentName);
1824 string axis = ns.attr<
string>(
e,
DD_CMU(axis));
1830 int nReplicas =
e.hasAttr(
DD_CMU(nReplicas)) ? ns.attr<
int>(
e,
DD_CMU(nReplicas)) : 0;
1834 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1836 "+++ Start executing Division of %s along %s (%d) with offset %6.3f and %6.3f to produce %s....",
1851 const TGeoTubeSeg* sh = (
const TGeoTubeSeg*)
shape;
1854 int numCopies = (
int)((sh->GetPhi2() - sh->GetPhi1()) / widthInDeg);
1858 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1860 "+++ ...divide %s along %s (%d) with offset %6.3f deg and %6.3f deg to produce %d copies",
1870 Volume child =
parent.divide(childName, static_cast<int>(axesmap.at(axis)), numCopies, startInDeg, widthInDeg);
1872 ns.context()->volumes[childName] =
child;
1876 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1878 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] is multivolume [%s]",
1881 parent.isValid() ?
"VALID" :
"INVALID",
1883 child.isValid() ?
"VALID" :
"INVALID",
1884 child->IsVolumeMulti() ?
"YES" :
"NO");
1888 double dy =
static_cast<const TGeoTrd1*
>(
shape)->GetDy();
1892 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1894 "+++ ...divide %s along %s (%d) with offset %6.3f cm and %6.3f cm to produce %d copies in %6.3f",
1907 ns.context()->volumes[childName] =
child;
1911 printout(ns.context()->debug_placements ? ALWAYS :
DEBUG,
1913 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] is multivolume [%s]",
1916 parent.isValid() ?
"VALID" :
"INVALID",
1918 child.isValid() ?
"VALID" :
"INVALID",
1919 child->IsVolumeMulti() ?
"YES" :
"NO");
1923 printout(
ERROR,
"DD4CMS",
"++ FAILED Division of a %s is not implemented yet!",
parent.solid().type());
1929 void Converter<DDLAlgorithm>::operator()(xml_h element)
const {
1931 xml_dim_t
e(element);
1932 string name =
e.nameStr();
1934 string type =
"DDCMS_" + ns.realName(
name);
1941 ns.context()->debug_algorithms ? ALWAYS :
DEBUG,
"DD4CMS",
"+++ Start executing algorithm %s....",
type.c_str());
1949 printout(ns.context()->debug_algorithms ? ALWAYS :
DEBUG,
1952 "+++ Executed algorithm: %08lX = %s",
1959 printout(
ERROR,
"DD4CMS",
"++ FAILED NOT ADDING SUBDETECTOR %08lX = %s",
ret,
name.c_str());
1962 template <
class InputIt,
class ForwardIt,
class BinOp>
1965 const auto pos = std::find_first_of(
first,
last, s_first, s_last);
1975 std::vector<string>
splitString(
const string&
str,
const string& delims =
",") {
1976 std::vector<string>
output;
1990 std::vector<double> splitNumeric(
const string&
str,
const string& delims =
",") {
1991 std::vector<double>
output;
2009 void Converter<DDLVector>::operator()(xml_h element)
const {
2013 xml_dim_t
e(element);
2014 string name = ns.prepend(
e.nameStr());
2015 string type = ns.attr<
string>(
e, _U(
type));
2016 string nEntries = ns.attr<
string>(
e,
DD_CMU(nEntries));
2017 string val =
e.text();
2018 val.erase(remove_if(
val.begin(),
val.end(), [](
unsigned char x) {
return isspace(x); }),
val.end());
2022 printout(ns.context()->debug_constants ? ALWAYS :
DEBUG,
2024 "+++ Vector<%s>: %s[%s]: %s",
2033 std::vector<double>
results = splitNumeric(
val);
2042 "++ Unresolved Vector<%s>: %s[%s]: %s. Try to resolve later. [%s]",
2057 void Converter<debug>::operator()(xml_h dbg)
const {
2059 if (dbg.hasChild(
DD_CMU(debug_constants)))
2060 ns.setContext()->debug_constants =
true;
2061 if (dbg.hasChild(
DD_CMU(debug_materials)))
2062 ns.setContext()->debug_materials =
true;
2063 if (dbg.hasChild(
DD_CMU(debug_rotations)))
2064 ns.setContext()->debug_rotations =
true;
2065 if (dbg.hasChild(
DD_CMU(debug_shapes)))
2066 ns.setContext()->debug_shapes =
true;
2067 if (dbg.hasChild(
DD_CMU(debug_volumes)))
2068 ns.setContext()->debug_volumes =
true;
2069 if (dbg.hasChild(
DD_CMU(debug_placements)))
2070 ns.setContext()->debug_placements =
true;
2071 if (dbg.hasChild(
DD_CMU(debug_namespaces)))
2072 ns.setContext()->debug_namespaces =
true;
2073 if (dbg.hasChild(
DD_CMU(debug_includes)))
2074 ns.setContext()->debug_includes =
true;
2075 if (dbg.hasChild(
DD_CMU(debug_algorithms)))
2076 ns.setContext()->debug_algorithms =
true;
2077 if (dbg.hasChild(
DD_CMU(debug_specpars)))
2078 ns.setContext()->debug_specpars =
true;
2082 void Converter<DDRegistry>::operator()(xml_h )
const {
2084 DDRegistry*
res = _option<DDRegistry>();
2092 "+++ RESOLVING %ld unknown constants..... (out of %ld)",
2093 res->unresolvedConst.size(),
2094 res->originalConst.size());
2097 while (!
res->unresolvedConst.empty()) {
2098 for (
auto&
i :
res->unresolvedConst) {
2099 const string&
n =
i.first;
2101 string&
v =
i.second;
2103 for (
idx =
v.find(
'[', 0);
idx != string::npos;
idx =
v.find(
'[',
idx + 1)) {
2104 idq =
v.find(
']',
idx + 1);
2106 auto r =
res->originalConst.find(
rep);
2107 if (r !=
res->originalConst.end()) {
2108 rep =
"(" + (*r).second +
")";
2112 if (
v.find(
']') == string::npos) {
2113 if (
v.find(
"-+") != string::npos ||
v.find(
"+-") != string::npos) {
2114 while ((
idx =
v.find(
"-+")) != string::npos)
2115 v.replace(
idx, 2,
"-");
2116 while ((
idx =
v.find(
"+-")) != string::npos)
2117 v.replace(
idx, 2,
"-");
2124 "+++ [%06ld] ---------- %-40s = %s",
2125 res->unresolvedConst.size() - 1,
2127 res->originalConst[
n].c_str());
2131 ns.addConstantNS(
n,
v,
"number");
2132 res->unresolvedConst.erase(
n);
2136 if (++
count > 10000)
2139 if (!
res->unresolvedConst.empty()) {
2140 for (
const auto&
e :
res->unresolvedConst)
2141 printout(
ERROR,
"DD4CMS",
"+++ Unresolved constant: %-40s = %s.",
e.first.c_str(),
e.second.c_str());
2142 except(
"DD4CMS",
"++ FAILED to resolve %ld constant entries:",
res->unresolvedConst.size());
2144 res->unresolvedConst.clear();
2145 res->originalConst.clear();
2149 void Converter<print_xml_doc>::operator()(xml_h element)
const {
2150 string fname = xml::DocumentHandler::system_path(element);
2154 printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS :
DEBUG,
2156 "+++ Processing data from: %s",
2164 xml_elt_t dddef(element);
2168 ns.addConstantNS(
"world_x",
"101*m",
"number");
2169 ns.addConstantNS(
"world_y",
"101*m",
"number");
2170 ns.addConstantNS(
"world_z",
"450*m",
"number");
2171 ns.addConstantNS(
"Air",
"materials:Air",
"string");
2172 ns.addConstantNS(
"Vacuum",
"materials:Vacuum",
"string");
2174 string fname = xml::DocumentHandler::system_path(element);
2175 bool open_geometry = dddef.hasChild(
DD_CMU(open_geometry)) ? dddef.child(
DD_CMU(open_geometry)) :
true;
2176 bool close_geometry = dddef.hasChild(
DD_CMU(close_geometry)) ? dddef.hasChild(
DD_CMU(close_geometry)) :
true;
2178 xml_coll_t(dddef, _U(
debug)).for_each(Converter<debug>(det, &
context));
2183 printout(
INFO,
"DD4CMS",
"+++ Processing the CMS detector description %s",
fname.c_str());
2186 Converter<print_xml_doc> print_doc(det, &
context);
2189 res.unresolvedConst.reserve(2000);
2190 res.originalConst.reserve(6000);
2191 print_doc((
doc = dddef.document()).
root());
2192 xml_coll_t(dddef,
DD_CMU(ConstantsSection)).for_each(Converter<ConstantsSection>(det, &
context, &
res));
2193 xml_coll_t(dddef,
DD_CMU(RotationSection)).for_each(Converter<RotationSection>(det, &
context));
2194 xml_coll_t(dddef,
DD_CMU(MaterialSection)).for_each(Converter<MaterialSection>(det, &
context));
2196 xml_coll_t(dddef,
DD_CMU(IncludeSection)).for_each(
DD_CMU(Include), Converter<include_load>(det, &
context, &
res));
2198 for (xml::Document
d :
res.includes) {
2200 Converter<include_constants>(det, &
context, &
res)((
doc =
d).root());
2203 Converter<DDRegistry>(det, &
context, &
res)(dddef);
2209 "+++ RESOLVING %ld Vectors.....",
2210 context.unresolvedVectors.size());
2212 while (!
context.unresolvedVectors.empty()) {
2213 for (
auto it =
context.unresolvedVectors.begin(); it !=
context.unresolvedVectors.end();) {
2214 std::vector<double>
result;
2215 for (
const auto&
i : it->second) {
2216 result.emplace_back(dd4hep::_toDouble(
i));
2218 registry->insert({it->first,
result});
2220 it =
context.unresolvedVectors.erase(it);
2225 for (xml::Document
d :
res.includes) {
2227 xml_coll_t(
d.root(),
DD_CMU(MaterialSection)).for_each(Converter<MaterialSection>(det, &
context));
2229 if (open_geometry) {
2231 ns.addVolume(det.worldVolume());
2233 for (xml::Document
d :
res.includes) {
2235 xml_coll_t(
d.root(),
DD_CMU(RotationSection)).for_each(Converter<RotationSection>(det, &
context));
2237 for (xml::Document
d :
res.includes) {
2239 xml_coll_t(
d.root(),
DD_CMU(SolidSection)).for_each(Converter<SolidSection>(det, &
context));
2241 for (xml::Document
d :
res.includes) {
2243 xml_coll_t(
d.root(),
DD_CMU(LogicalPartSection)).for_each(Converter<LogicalPartSection>(det, &
context));
2245 for (xml::Document
d :
res.includes) {
2249 for (xml::Document
d :
res.includes) {
2251 xml_coll_t(
d.root(),
DD_CMU(PosPartSection)).for_each(Converter<PosPartSection>(det, &
context));
2253 for (xml::Document
d :
res.includes) {
2255 xml_coll_t(
d.root(),
DD_CMU(SpecParSection)).for_each(Converter<SpecParSection>(det, &
context));
2259 for (xml::Document
d :
res.includes)
2260 Converter<include_unload>(det, &
context, &
res)(
d.root());
2262 print_doc((
doc = dddef.document()).
root());
2264 xml_coll_t(dddef,
DD_CMU(SolidSection)).for_each(Converter<SolidSection>(det, &
context));
2271 while (!
context.unresolvedShapes.empty()) {
2272 for (
auto it =
context.unresolvedShapes.begin(); it !=
context.unresolvedShapes.end();) {
2273 auto const&
name = it->first;
2274 auto const& aname = std::visit([](
auto&&
arg) ->
std::string {
return arg.firstSolidName; }, it->second);
2275 auto const& bname = std::visit([](
auto&&
arg) ->
std::string {
return arg.secondSolidName; }, it->second);
2277 auto const& ait =
context.shapes.find(aname);
2278 if (ait->second.isValid()) {
2279 auto const&
bit =
context.shapes.find(bname);
2280 if (
bit->second.isValid()) {
2281 dd4hep::Solid
shape =
2282 std::visit([&ait, &
bit](
auto&&
arg) -> dd4hep::Solid {
return arg.make(ait->second,
bit->second); },
2285 it =
context.unresolvedShapes.erase(it);
2293 xml_coll_t(dddef,
DD_CMU(LogicalPartSection)).for_each(Converter<LogicalPartSection>(det, &
context));
2295 xml_coll_t(dddef,
DD_CMU(PosPartSection)).for_each(Converter<PosPartSection>(det, &
context));
2296 xml_coll_t(dddef,
DD_CMU(SpecParSection)).for_each(Converter<SpecParSection>(det, &
context));
2298 printout(
ERROR,
"DD4CMS",
"Exception while processing xml source:%s",
doc.uri().c_str());
2299 printout(
ERROR,
"DD4CMS",
"----> %s",
e.what());
2304 if (close_geometry) {
2306 Volume geomv = ns.volume(
"cms:OCMS",
false);
2307 if (geomv.isValid())
2308 wv.placeVolume(geomv, 1);
2309 Volume mfv = ns.volume(
"cmsMagneticField:MAGF",
false);
2311 wv.placeVolume(mfv, 1);
2312 Volume mfv1 = ns.volume(
"MagneticFieldVolumes:MAGF",
false);
2314 wv.placeVolume(mfv1, 1);
2317 det.manager().CloseGeometry();
2321 printout(
INFO,
"DDDefinition",
"+++ Finished processing %s",
fname.c_str());
2324 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.
SOARotation< float > Rotation
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
Geom::Theta< T > theta() const
DDLRotationSequence handles a set of Rotations.
void for_each_token(InputIt first, InputIt last, ForwardIt s_first, ForwardIt s_last, BinOp binary_op)
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