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" 11 #include "XML/Utilities.h" 18 #include "TGeoManager.h" 19 #include "TGeoMaterial.h" 36 UInt_t unique_mat_id = 0xAFFEFEED;
39 class include_constants;
44 class ConstantsSection;
52 class MaterialSection;
56 class RotationSection;
65 class LogicalPartSection;
69 class DDLExtrudedPolygon;
85 class DDLIntersectionSolid;
86 class DDLSubtractionSolid;
97 template <>
void Converter<debug>::operator()(xml_h element)
const;
98 template <>
void Converter<print_xml_doc>::operator()(xml_h element)
const;
99 template <>
void Converter<disabled_algo>::operator()(xml_h element)
const;
102 template <>
void Converter<ConstantsSection>::operator()(xml_h element)
const;
103 template <>
void Converter<DDLConstant>::operator()(xml_h element)
const;
104 template <>
void Converter<DDRegistry>::operator()(xml_h element)
const;
107 template <>
void Converter<vissection>::operator()(xml_h element)
const;
109 template <>
void Converter<vis>::operator()(xml_h element)
const;
112 template <>
void Converter<MaterialSection>::operator()(xml_h element)
const;
113 template <>
void Converter<DDLElementaryMaterial>::operator()(xml_h element)
const;
114 template <>
void Converter<DDLCompositeMaterial>::operator()(xml_h element)
const;
117 template <>
void Converter<RotationSection>::operator()(xml_h element)
const;
119 template <>
void Converter<DDLRotation>::operator()(xml_h element)
const;
121 template <>
void Converter<DDLRotationSequence>::operator()(xml_h element)
const;
123 template <>
void Converter<DDLRotationByAxis>::operator()(xml_h element)
const;
124 template <>
void Converter<DDLTransform3D>::operator()(xml_h element)
const;
127 template <>
void Converter<LogicalPartSection>::operator()(xml_h element)
const;
128 template <>
void Converter<DDLLogicalPart>::operator()(xml_h element)
const;
130 template <>
void Converter<PosPartSection>::operator()(xml_h element)
const;
132 template <>
void Converter<DDLPosPart>::operator()(xml_h element)
const;
135 template <>
void Converter<SolidSection>::operator()(xml_h element)
const;
137 template <>
void Converter<DDLUnionSolid>::operator()(xml_h element)
const;
139 template <>
void Converter<DDLSubtractionSolid>::operator()(xml_h element)
const;
141 template <>
void Converter<DDLIntersectionSolid>::operator()(xml_h element)
const;
143 template <>
void Converter<DDLPseudoTrap>::operator()(xml_h element)
const;
145 template <>
void Converter<DDLExtrudedPolygon>::operator()(xml_h element)
const;
147 template <>
void Converter<DDLShapeless>::operator()(xml_h element)
const;
149 template <>
void Converter<DDLTrapezoid>::operator()(xml_h element)
const;
151 template <>
void Converter<DDLPolycone>::operator()(xml_h element)
const;
153 template <>
void Converter<DDLPolyhedra>::operator()(xml_h element)
const;
155 template <>
void Converter<DDLEllipticalTube>::operator()(xml_h element)
const;
157 template <>
void Converter<DDLTorus>::operator()(xml_h element)
const;
159 template <>
void Converter<DDLTubs>::operator()(xml_h element)
const;
161 template <>
void Converter<DDLCutTubs>::operator()(xml_h element)
const;
163 template <>
void Converter<DDLTruncTubs>::operator()(xml_h element)
const;
165 template <>
void Converter<DDLSphere>::operator()(xml_h element)
const;
167 template <>
void Converter<DDLTrd1>::operator()(xml_h element)
const;
169 template <>
void Converter<DDLCone>::operator()(xml_h element)
const;
171 template <>
void Converter<DDLBox>::operator()(xml_h element)
const;
173 template <>
void Converter<DDLAlgorithm>::operator()(xml_h element)
const;
175 template <>
void Converter<DDLVector>::operator()(xml_h element)
const;
178 template <>
void Converter<include_load>::operator()(xml_h element)
const;
180 template <>
void Converter<include_unload>::operator()(xml_h element)
const;
182 template <>
void Converter<include_constants>::operator()(xml_h element)
const;
186 template <>
void Converter<ConstantsSection>::operator()(xml_h element)
const {
193 template <>
void Converter<vissection>::operator()(xml_h element)
const {
195 xml_coll_t(element,
_CMU(
vis)).for_each(Converter<vis>(
description,_ns.context,optional));
199 template <>
void Converter<MaterialSection>::operator()(xml_h element)
const {
201 xml_coll_t(element,
_CMU(ElementaryMaterial)).for_each(Converter<DDLElementaryMaterial>(
description,_ns.context,optional));
202 xml_coll_t(element,
_CMU(CompositeMaterial)).for_each(Converter<DDLCompositeMaterial>(
description,_ns.context,optional));
205 template <>
void Converter<RotationSection>::operator()(xml_h element)
const {
207 xml_coll_t(element,
_CMU(Rotation)).for_each(Converter<DDLRotation>(
description,_ns.context,optional));
208 xml_coll_t(element,
_CMU(RotationSequence)).for_each(Converter<DDLRotationSequence>(
description,_ns.context,optional));
209 xml_coll_t(element,
_CMU(RotationByAxis)).for_each(Converter<DDLRotationByAxis>(
description,_ns.context,optional));
212 template <>
void Converter<PosPartSection>::operator()(xml_h element)
const {
214 xml_coll_t(element,
_CMU(PosPart)).for_each(Converter<DDLPosPart>(
description,_ns.context,optional));
218 template <>
void Converter<LogicalPartSection>::operator()(xml_h element)
const {
220 xml_coll_t(element,
_CMU(LogicalPart)).for_each(Converter<DDLLogicalPart>(
description,_ns.context,optional));
223 template <>
void Converter<disabled_algo>::operator()(xml_h element)
const {
229 template <>
void Converter<SolidSection>::operator()(xml_h element)
const {
231 for(xml_coll_t solid(element, _U(star)); solid; ++solid) {
232 string tag = solid.tag();
234 switch(
hash( solid.tag()))
239 case hash(
"Polycone"):
240 Converter<DDLPolycone>(
description,_ns.context,optional)(solid);
242 case hash(
"Polyhedra"):
243 Converter<DDLPolyhedra>(
description,_ns.context,optional)(solid);
248 case hash(
"CutTubs"):
249 Converter<DDLCutTubs>(
description,_ns.context,optional)(solid);
251 case hash(
"TruncTubs"):
252 Converter<DDLTruncTubs>(
description,_ns.context,optional)(solid);
258 Converter<DDLTrd1>(
description,_ns.context,optional)(solid);
266 case hash(
"EllipticalTube"):
272 case hash(
"PseudoTrap"):
275 case hash(
"ExtrudedPolygon"):
276 Converter<DDLExtrudedPolygon>(
description,_ns.context,optional)(solid);
278 case hash(
"Trapezoid"):
281 case hash(
"UnionSolid"):
282 Converter<DDLUnionSolid>(
description,_ns.context,optional)(solid);
284 case hash(
"SubtractionSolid"):
285 Converter<DDLSubtractionSolid>(
description,_ns.context,optional)(solid);
287 case hash(
"IntersectionSolid"):
288 Converter<DDLIntersectionSolid>(
description,_ns.context,optional)(solid);
290 case hash(
"ShapelessSolid"):
291 Converter<DDLShapeless>(
description,_ns.context,optional)(solid);
294 throw std::runtime_error(
"Request to process unknown shape '" + xml_dim_t(solid).nameStr() +
"' [" + tag +
"]");
301 template <>
void Converter<DDLConstant>::operator()(xml_h element)
const {
303 DDRegistry*
res = _option<DDRegistry>();
304 xml_dim_t constant = element;
305 xml_dim_t par = constant.parent();
306 bool eval = par.hasAttr(_U(eval)) ? par.attr<
bool>(_U(eval)) :
false;
307 string val = constant.valueStr();
308 string nam = constant.nameStr();
309 string real = _ns.prepend(nam);
310 string typ = eval ?
"number" :
"string";
311 size_t idx = val.find(
'[');
313 if ( constant.hasAttr(_U(
type)) )
314 typ = constant.typeStr();
316 if ( idx == string::npos || typ ==
"string" ) {
318 _ns.addConstant(nam, val, typ);
319 res->allConst[real] =
val;
320 res->originalConst[real] =
val;
323 printout(
INFO,
"MyDDCMS",
"++ Unresolved constant: %s = %s [%s]. Try to resolve later. [%s]",
324 real.c_str(), val.c_str(), typ.c_str(), e.what());
329 while ( idx != string::npos ) {
331 size_t idp = val.find(
':',idx);
332 size_t idq = val.find(
']',idx);
333 if ( idp == string::npos || idp > idq )
334 val.insert(idx,_ns.name());
335 else if ( idp != string::npos && idp < idq )
337 idx = val.find(
'[',idx);
339 while ( (idx=val.find(
':')) != string::npos ) val[
idx]=
'_';
340 printout(_ns.context->debug_constants ? ALWAYS :
DEBUG,
341 "Constant",
"Unresolved: %s -> %s",real.c_str(),val.c_str());
342 res->allConst[real] =
val;
343 res->originalConst[real] =
val;
344 res->unresolvedConst[real] =
val;
355 template <>
void Converter<vis>::operator()(xml_h e)
const {
357 VisAttr attr(e.attr<
string>(_U(
name)));
358 float red = e.hasAttr(_U(
r)) ? e.attr<
float>(_U(
r)) : 1.0
f;
359 float green = e.hasAttr(_U(
g)) ? e.attr<
float>(_U(
g)) : 1.0
f;
360 float blue = e.hasAttr(_U(
b)) ? e.attr<
float>(_U(
b)) : 1.0
f;
362 printout(_ns.context->debug_visattr ? ALWAYS : DEBUG,
"Compact",
363 "++ Converting VisAttr structure: %-16s. R=%.3f G=%.3f B=%.3f",
365 attr.setColor(red, green, blue);
366 if (e.hasAttr(_U(
alpha)))
367 attr.setAlpha(e.attr<
float>(_U(
alpha)));
368 if (e.hasAttr(_U(visible)))
369 attr.setVisible(e.attr<
bool>(_U(visible)));
372 if (ls ==
"unbroken")
373 attr.setLineStyle(VisAttr::SOLID);
374 else if (ls ==
"broken")
375 attr.setLineStyle(VisAttr::DASHED);
378 attr.setLineStyle(VisAttr::SOLID);
380 if (e.hasAttr(_U(drawingStyle))) {
381 string ds = e.attr<
string>(_U(drawingStyle));
382 if (ds ==
"wireframe")
383 attr.setDrawingStyle(VisAttr::WIREFRAME);
384 else if (ds ==
"solid")
385 attr.setDrawingStyle(VisAttr::SOLID);
388 attr.setDrawingStyle(VisAttr::SOLID);
390 if (e.hasAttr(_U(showDaughters)))
391 attr.setShowDaughters(e.attr<
bool>(_U(showDaughters)));
393 attr.setShowDaughters(
true);
398 template <>
void Converter<DDLElementaryMaterial>::operator()(xml_h element)
const {
400 xml_dim_t xmat(element);
401 string nam = _ns.prepend(xmat.nameStr());
403 TGeoMaterial* mat = mgr.GetMaterial(nam.c_str());
404 if (
nullptr == mat ) {
405 const char* matname = nam.c_str();
406 double density = xmat.density();
408 double atomicNumber = xmat.attr<
double>(
_CMU(atomicNumber));
409 TGeoElementTable* tab = mgr.GetElementTable();
410 TGeoMixture*
mix =
new TGeoMixture(nam.c_str(), 1, density);
411 TGeoElement* elt = tab->FindElement(xmat.nameStr().c_str());
413 printout(_ns.context->debug_materials ? ALWAYS : DEBUG,
"MyDDCMS",
414 "+++ Converting material %-48s Density: %.3f.",
415 (
'"'+nam+
'"').c_str(), density);
419 "+++ Converter<ElementaryMaterial> No element present with name:%s [FAKE IT]",
421 int n =
int(atomicNumber/2e0);
423 elt =
new TGeoElement(xmat.nameStr().c_str(),
"CMS element",
n,atomicNumber);
426 if ( elt->Z() == 0 ) {
427 int n =
int(atomicNumber/2e0);
429 elt =
new TGeoElement((xmat.nameStr()+
"-CMS").c_str(),
"CMS element",
n,atomicNumber);
431 mix->AddElement(elt, 1.0);
434 TGeoMedium* medium = mgr.GetMedium(matname);
435 if (
nullptr == medium) {
437 medium =
new TGeoMedium(matname, unique_mat_id, mix);
438 medium->SetTitle(
"material");
439 medium->SetUniqueID(unique_mat_id);
445 template <>
void Converter<DDLCompositeMaterial>::operator()(xml_h element)
const {
447 xml_dim_t xmat(element);
448 string nam = _ns.prepend(xmat.nameStr());
450 TGeoMaterial* mat = mgr.GetMaterial(nam.c_str());
451 if (
nullptr == mat ) {
452 const char* matname = nam.c_str();
453 double density = xmat.density();
454 xml_coll_t composites(xmat,
_CMU(MaterialFraction));
455 TGeoMixture* mix =
new TGeoMixture(nam.c_str(), composites.size(), density);
457 printout(_ns.context->debug_materials ? ALWAYS : DEBUG,
"MyDDCMS",
458 "++ Converting material %-48s Density: %.3f.",
459 (
'"'+nam+
'"').c_str(), density);
461 for (composites.reset(); composites; ++composites) {
462 xml_dim_t xfrac(composites);
463 xml_dim_t xfrac_mat(xfrac.child(
_CMU(rMaterial)));
465 string fracname = _ns.realName(xfrac_mat.nameStr());
467 TGeoMaterial* frac_mat = mgr.GetMaterial(fracname.c_str());
469 mix->AddElement(frac_mat, fraction);
472 printout(
WARNING,
"MyDDCMS",
"+++ Composite material \"%s\" not present!",
477 TGeoMedium* medium = mgr.GetMedium(matname);
478 if (
nullptr == medium) {
480 medium =
new TGeoMedium(matname, unique_mat_id, mix);
481 medium->SetTitle(
"material");
482 medium->SetUniqueID(unique_mat_id);
488 template <>
void Converter<DDLRotation>::operator()(xml_h element)
const {
491 xml_dim_t xrot(element);
492 string nam = xrot.nameStr();
493 double thetaX = xrot.hasAttr(
_CMU(thetaX)) ? _ns.attr<
double>(xrot,
_CMU(thetaX)) : 0e0;
494 double phiX = xrot.hasAttr(
_CMU(phiX)) ? _ns.attr<
double>(xrot,
_CMU(phiX)) : 0e0;
495 double thetaY = xrot.hasAttr(
_CMU(thetaY)) ? _ns.attr<
double>(xrot,
_CMU(thetaY)) : 0e0;
496 double phiY = xrot.hasAttr(
_CMU(phiY)) ? _ns.attr<
double>(xrot,
_CMU(phiY)) : 0e0;
497 double thetaZ = xrot.hasAttr(
_CMU(thetaZ)) ? _ns.attr<
double>(xrot,
_CMU(thetaZ)) : 0e0;
498 double phiZ = xrot.hasAttr(
_CMU(phiZ)) ? _ns.attr<
double>(xrot,
_CMU(phiZ)) : 0e0;
501 "MyDDCMS",
"+++ Adding rotation: %-32s: (theta/phi)[rad] X: %6.3f %6.3f Y: %6.3f %6.3f Z: %6.3f %6.3f",
503 _ns.addRotation(nam, rot);
507 template <>
void Converter<DDLRotationSequence>::operator()(xml_h element)
const {
510 xml_dim_t xrot(element);
511 string nam = xrot.nameStr();
513 xml_coll_t rotations(xrot,
_CMU(RotationByAxis));
514 for( rotations.reset(); rotations; ++rotations ) {
515 string axis = _ns.attr<
string>(rotations,
_CMU(axis));
516 double angle = _ns.attr<
double>(rotations,_U(angle));
519 "MyDDCMS",
"+ Adding rotation to: %-29s: (axis/angle)[rad] Axis: %s Angle: %6.3f",
520 nam.c_str(), axis.c_str(),
angle);
525 rot.GetComponents(xx,xy,xz,yx,yy,yz,zx,zy,zz);
527 "MyDDCMS",
"+++ Adding rotation sequence: %-23s: %6.3f %6.3f %6.3f, %6.3f %6.3f %6.3f, %6.3f %6.3f %6.3f",
528 _ns.prepend(nam).c_str(),
xx,
xy,
xz, yx,
yy,
yz, zx, zy,
zz);
529 _ns.addRotation(nam, rot);
533 template <>
void Converter<DDLRotationByAxis>::operator()(xml_h element)
const {
536 xml_dim_t xrot(element);
537 xml_dim_t par(xrot.parent());
538 if( xrot.hasAttr(_U(
name))) {
539 string nam = xrot.nameStr();
540 string axis = _ns.attr<
string>(xrot,
_CMU(axis));
541 double angle = _ns.attr<
double>(xrot,_U(angle));
545 "MyDDCMS",
"+++ Adding rotation: %-32s: (axis/angle)[rad] Axis: %s Angle: %6.3f",
546 _ns.prepend(nam).c_str(), axis.c_str(),
angle);
547 _ns.addRotation(nam, rot);
552 template <>
void Converter<DDLLogicalPart>::operator()(xml_h element)
const {
554 xml_dim_t
e(element);
555 string sol = e.child(
_CMU(rSolid)).attr<
string>(_U(
name));
556 string mat = e.child(
_CMU(rMaterial)).attr<
string>(_U(
name));
557 _ns.addVolume(
Volume(e.nameStr(), _ns.solid(sol), _ns.material(mat)));
561 template <>
void Converter<DDLTransform3D>::operator()(xml_h element)
const {
563 Transform3D* tr = _option<Transform3D>();
564 xml_dim_t
e(element);
565 xml_dim_t translation = e.child(
_CMU(Translation),
false);
567 xml_dim_t refRotation = e.child(
_CMU(rRotation),
false);
571 if ( translation.ptr() ) {
572 double x = _ns.attr<
double>(translation,_U(x));
573 double y = _ns.attr<
double>(translation,_U(y));
574 double z = _ns.attr<
double>(translation,_U(z));
575 pos = Position(x,y,z);
577 if ( rotation.ptr() ) {
578 double x = _ns.attr<
double>(
rotation,_U(x));
579 double y = _ns.attr<
double>(
rotation,_U(y));
580 double z = _ns.attr<
double>(
rotation,_U(z));
581 rot = RotationZYX(z,y,x);
583 else if ( refRotation.ptr() ) {
584 rot = _ns.rotation(refRotation.nameStr());
586 *tr = Transform3D(rot,pos);
590 template <>
void Converter<DDLPosPart>::operator()(xml_h element)
const {
592 xml_dim_t
e(element);
593 int copy = e.attr<
int>(
_CMU(copyNumber));
594 string parent_nam = _ns.attr<
string>(e.child(
_CMU(rParent)),_U(
name));
595 string child_nam = _ns.attr<
string>(e.child(
_CMU(rChild)),_U(
name));
599 printout(_ns.context->debug_placements ? ALWAYS : DEBUG,
"MyDDCMS",
600 "+++ %s Parent: %-24s [%s] Child: %-32s [%s] copy:%d",
602 parent_nam.c_str(), parent.isValid() ?
"VALID" :
"INVALID",
603 child_nam.c_str(), child.isValid() ?
"VALID" :
"INVALID",
606 if ( child.isValid() ) {
608 Converter<DDLTransform3D>(
description,param,&trafo)(element);
609 pv = parent.placeVolume(child,copy,trafo);
611 if ( !pv.isValid() ) {
612 printout(
ERROR,
"MyDDCMS",
"+++ Placement FAILED! Parent:%s Child:%s Valid:%s",
613 parent.name(), child_nam.c_str(), yes_no(child.isValid()));
617 template <
typename TYPE>
620 xml_dim_t
e(element);
621 string nam = e.nameStr();
626 if ( e.hasChild(
_CMU(rSolid)) ) {
627 for(xml_coll_t
c(element,
_CMU(rSolid)); cnt<2 &&
c; ++
c, ++cnt)
628 solids[cnt] = _ns.
solid(c.attr<
string>(_U(
name)));
631 if ( (solids[0] = _ns.
solid(e.attr<
string>(
_CMU(firstSolid)))).isValid() ) ++cnt;
632 if ( (solids[1] = _ns.
solid(e.attr<
string>(
_CMU(secondSolid)))).isValid() ) ++cnt;
635 except(
"MyDDCMS",
"+++ Failed to create boolean solid %s. Found only %d parts.",nam.c_str(), cnt);
638 "+++ BooleanSolid: %s Left: %-32s Right: %-32s",
639 nam.c_str(), solids[0]->GetName(), solids[1]->GetName());
641 if ( solids[0].isValid() && solids[1].isValid() ) {
643 Converter<DDLTransform3D>(*context->
description,context,&trafo)(element);
644 boolean = TYPE(solids[0],solids[1],trafo);
646 if ( !
boolean.isValid() )
647 except(
"MyDDCMS",
"+++ FAILED to construct subtraction solid: %s",nam.c_str());
652 template <>
void Converter<DDLUnionSolid>::operator()(xml_h element)
const {
653 convert_boolean<UnionSolid>(_param<cms::DDParsingContext>(),element);
657 template <>
void Converter<DDLSubtractionSolid>::operator()(xml_h element)
const {
658 convert_boolean<SubtractionSolid>(_param<cms::DDParsingContext>(),element);
662 template <>
void Converter<DDLIntersectionSolid>::operator()(xml_h element)
const {
663 convert_boolean<IntersectionSolid>(_param<cms::DDParsingContext>(),element);
667 template <>
void Converter<DDLPolycone>::operator()(xml_h element)
const {
669 xml_dim_t
e(element);
670 string nam = e.nameStr();
671 double startPhi = _ns.
attr<
double>(
e,
_CMU(startPhi));
673 vector<double>
z, rmin, rmax,
r;
675 for(xml_coll_t rzpoint(element,
_CMU(RZPoint)); rzpoint; ++rzpoint) {
676 z.emplace_back(_ns.
attr<
double>(rzpoint,_U(z)));
677 r.emplace_back(_ns.
attr<
double>(rzpoint,_U(r)));
680 for(xml_coll_t zplane(element,
_CMU(ZSection)); zplane; ++zplane) {
683 z.emplace_back(_ns.
attr<
double>(zplane,_U(z)));
686 "+ Polycone: startPhi=%10.3f [rad] deltaPhi=%10.3f [rad] %4ld z-planes",
687 startPhi, deltaPhi, z.size());
688 _ns.
addSolid(nam, Polycone(startPhi,deltaPhi,rmin,rmax,z));
692 "+ Polycone: startPhi=%10.3f [rad] deltaPhi=%10.3f [rad] %4ld z-planes and %4ld radii",
693 startPhi, deltaPhi, z.size(), r.size());
694 _ns.
addSolid(nam, Polycone(startPhi,deltaPhi,r,z));
699 template <>
void Converter<DDLExtrudedPolygon>::operator()(xml_h element)
const {
701 xml_dim_t
e(element);
702 string nam = e.nameStr();
703 vector<double> pt_x, pt_y, sec_x, sec_y, sec_z, sec_scale;
705 for(xml_coll_t sec(element,
_CMU(ZXYSection)); sec; ++sec) {
706 sec_z.emplace_back(_ns.
attr<
double>(sec,_U(
z)));
707 sec_x.emplace_back(_ns.
attr<
double>(sec,_U(
x)));
708 sec_y.emplace_back(_ns.
attr<
double>(sec,_U(
y)));
709 sec_scale.emplace_back(_ns.
attr<
double>(sec,
_CMU(
scale),1.0));
711 for(xml_coll_t
pt(element,
_CMU(XYPoint));
pt; ++
pt) {
712 pt_x.emplace_back(_ns.
attr<
double>(
pt,_U(
x)));
713 pt_y.emplace_back(_ns.
attr<
double>(
pt,_U(
y)));
716 "+ ExtrudedPolygon: %4ld points %4ld zxy sections",
717 pt_x.size(), sec_z.size());
722 template <>
void Converter<DDLPolyhedra>::operator()(xml_h element)
const {
724 xml_dim_t
e(element);
725 string nam = e.nameStr();
726 double numSide = _ns.
attr<
int>(
e,
_CMU(numSide));
727 double startPhi = _ns.
attr<
double>(
e,
_CMU(startPhi));
729 vector<double>
z, rmin, rmax;
731 for(xml_coll_t zplane(element,
_CMU(RZPoint)); zplane; ++zplane) {
732 rmin.emplace_back(0.0);
733 rmax.emplace_back(_ns.
attr<
double>(zplane,_U(
r)));
734 z.emplace_back(_ns.
attr<
double>(zplane,_U(z)));
736 for(xml_coll_t zplane(element,
_CMU(ZSection)); zplane; ++zplane) {
739 z.emplace_back(_ns.
attr<
double>(zplane,_U(z)));
742 "+ Polyhedra:startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] %4d sides %4ld z-planes",
743 startPhi, deltaPhi, numSide, z.size());
748 template <>
void Converter<DDLSphere>::operator()(xml_h element)
const {
750 xml_dim_t
e(element);
751 string nam = e.nameStr();
754 double startPhi = _ns.
attr<
double>(
e,
_CMU(startPhi));
756 double startTheta = _ns.
attr<
double>(
e,
_CMU(startTheta));
757 double deltaTheta = _ns.
attr<
double>(
e,
_CMU(deltaTheta));
759 "+ Sphere: r_inner=%8.3f [cm] r_outer=%8.3f [cm]" 760 " startPhi=%8.3f [rad] deltaPhi=%8.3f startTheta=%8.3f delteTheta=%8.3f [rad]",
761 rinner, router, startPhi, deltaPhi, startTheta, deltaTheta);
762 _ns.
addSolid(nam, Sphere(rinner, router, startTheta, deltaTheta, startPhi, deltaPhi));
766 template <>
void Converter<DDLTorus>::operator()(xml_h element)
const {
768 xml_dim_t
e(element);
769 string nam = e.nameStr();
770 double r = _ns.
attr<
double>(
e,
_CMU(torusRadius));
773 double startPhi = _ns.
attr<
double>(
e,
_CMU(startPhi));
776 "+ Torus: r=%10.3f [cm] r_inner=%10.3f [cm] r_outer=%10.3f [cm]" 777 " startPhi=%10.3f [rad] deltaPhi=%10.3f [rad]",
778 r, rinner, router, startPhi, deltaPhi);
779 _ns.
addSolid(nam, Torus(r, rinner, router, startPhi, deltaPhi));
783 template <>
void Converter<DDLPseudoTrap>::operator()(xml_h element)
const {
785 xml_dim_t
e(element);
786 string nam = e.nameStr();
787 double dx1 = _ns.
attr<
double>(
e,
_CMU(dx1));
788 double dy1 = _ns.
attr<
double>(
e,
_CMU(dy1));
789 double dx2 = _ns.
attr<
double>(
e,
_CMU(dx2));
790 double dy2 = _ns.
attr<
double>(
e,
_CMU(dy2));
791 double dz = _ns.
attr<
double>(
e,_U(dz));
793 bool atMinusZ = _ns.
attr<
bool> (
e,
_CMU(atMinusZ));
795 "+ Pseudotrap: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2=%.3f dy2=%.3f radius:%.3f atMinusZ:%s",
796 dz, dx1, dy1, dx2, dy2, r, yes_no(atMinusZ));
797 _ns.
addSolid(nam, PseudoTrap(dx1, dx2, dy1, dy2, dz, r, atMinusZ));
801 template <>
void Converter<DDLTrapezoid>::operator()(xml_h element)
const {
803 xml_dim_t
e(element);
804 string nam = e.nameStr();
805 double dz = _ns.
attr<
double>(
e,_U(dz));
806 double alp1 = _ns.
attr<
double>(
e,
_CMU(alp1));
807 double bl1 = _ns.
attr<
double>(
e,
_CMU(bl1));
808 double tl1 = _ns.
attr<
double>(
e,
_CMU(tl1));
809 double h1 = _ns.
attr<
double>(
e,
_CMU(h1));
810 double alp2 = _ns.
attr<
double>(
e,
_CMU(alp2));
811 double bl2 = _ns.
attr<
double>(
e,
_CMU(bl2));
812 double tl2 = _ns.
attr<
double>(
e,
_CMU(tl2));
813 double h2 = _ns.
attr<
double>(
e,
_CMU(h2));
814 double phi = _ns.
attr<
double>(
e,_U(phi),0.0);
815 double theta = _ns.
attr<
double>(
e,_U(theta),0.0);
818 "+ Trapezoid: dz=%10.3f [cm] alp1:%.3f bl1=%.3f tl1=%.3f alp2=%.3f bl2=%.3f tl2=%.3f h2=%.3f phi=%.3f theta=%.3f",
819 dz, alp1, bl1, tl1, h1, alp2, bl2, tl2, h2, phi, theta);
820 _ns.
addSolid( nam, Trap( dz, theta, phi, h1, bl1, tl1, alp1, h2, bl2, tl2, alp2 ));
824 template <>
void Converter<DDLTrd1>::operator()(xml_h element)
const {
826 xml_dim_t
e( element );
827 string nam = e.nameStr();
828 double dx1 = _ns.
attr<
double>(
e,
_CMU( dx1 ));
829 double dy1 = _ns.
attr<
double>(
e,
_CMU( dy1 ));
830 double dx2 = _ns.
attr<
double>(
e,
_CMU( dx2 ), 0.0 );
831 double dy2 = _ns.
attr<
double>(
e,
_CMU( dy2 ), dy1 );
834 "+ Trd1: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
835 dz, dx1, dy1, dx2, dy2);
840 template <>
void Converter<DDLTubs>::operator()(xml_h element)
const {
842 xml_dim_t
e(element);
843 string nam = e.nameStr();
847 double startPhi = _ns.
attr<
double>(
e,
_CMU(startPhi),0.0);
850 "+ Tubs: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]" 851 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]", dz, rmin, rmax, startPhi, deltaPhi);
852 _ns.
addSolid(nam, Tube(rmin,rmax,dz,startPhi,deltaPhi));
856 template <>
void Converter<DDLCutTubs>::operator()(xml_h element)
const {
858 xml_dim_t
e(element);
859 string nam = e.nameStr();
863 double startPhi = _ns.
attr<
double>(
e,
_CMU(startPhi));
865 double lx = _ns.
attr<
double>(
e,
_CMU(lx));
866 double ly = _ns.
attr<
double>(
e,
_CMU(ly));
867 double lz = _ns.
attr<
double>(
e,
_CMU(lz));
868 double tx = _ns.
attr<
double>(
e,
_CMU(tx));
869 double ty = _ns.
attr<
double>(
e,
_CMU(ty));
870 double tz = _ns.
attr<
double>(
e,
_CMU(tz));
872 "+ CutTube: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]" 873 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]...",
874 dz, rmin, rmax, startPhi, deltaPhi);
875 _ns.
addSolid(nam, CutTube(rmin,rmax,dz,startPhi,deltaPhi,lx,ly,lz,tx,ty,tz));
879 template <>
void Converter<DDLTruncTubs>::operator()(xml_h element)
const {
881 xml_dim_t
e(element);
882 string nam = e.nameStr();
883 double zhalf = _ns.
attr<
double>(
e,
_CMU(zHalf));
886 double startPhi = _ns.
attr<
double>(
e,
_CMU(startPhi));
888 double cutAtStart = _ns.
attr<
double>(
e,
_CMU(cutAtStart));
889 double cutAtDelta = _ns.
attr<
double>(
e,
_CMU(cutAtDelta));
890 bool cutInside = _ns.
attr<
bool>(
e,
_CMU(cutInside));
892 "+ TruncTube:zHalf=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]" 893 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] atStart=%8.3f [cm] atDelta=%8.3f [cm] inside:%s",
894 zhalf, rmin, rmax, startPhi, deltaPhi, cutAtStart, cutAtDelta, yes_no(cutInside));
895 _ns.
addSolid(nam, TruncatedTube(zhalf,rmin,rmax,startPhi,deltaPhi,cutAtStart,cutAtDelta,cutInside));
899 template <>
void Converter<DDLEllipticalTube>::operator()(xml_h element)
const {
901 xml_dim_t
e(element);
902 string nam = e.nameStr();
907 "+ EllipticalTube xSemiAxis=%8.3f [cm] ySemiAxis=%8.3f [cm] zHeight=%8.3f [cm]",dx,dy,dz);
908 _ns.
addSolid(nam, EllipticalTube(dx,dy,dz));
912 template <>
void Converter<DDLCone>::operator()(xml_h element)
const {
914 xml_dim_t
e(element);
915 string nam = e.nameStr();
917 double rmin1 = _ns.
attr<
double>(
e,
_CMU(rMin1));
918 double rmin2 = _ns.
attr<
double>(
e,
_CMU(rMin2));
919 double rmax1 = _ns.
attr<
double>(
e,
_CMU(rMax1));
920 double rmax2 = _ns.
attr<
double>(
e,
_CMU(rMax2));
921 double startPhi = _ns.
attr<
double>(
e,
_CMU(startPhi));
925 "+ Cone: dz=%8.3f [cm]" 926 " rmin1=%8.3f [cm] rmax1=%8.3f [cm]" 927 " rmin2=%8.3f [cm] rmax2=%8.3f [cm]" 928 " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]",
929 dz, rmin1, rmax1, rmin2, rmax2, startPhi, deltaPhi);
930 _ns.
addSolid(nam, ConeSegment(dz,rmin1,rmax1,rmin2,rmax2,startPhi,phi2));
934 template <>
void Converter<DDLShapeless>::operator()(xml_h element)
const {
936 xml_dim_t
e(element);
937 string nam = e.nameStr();
939 "+ Shapeless: THIS ONE CAN ONLY BE USED AT THE VOLUME LEVEL -> Assembly%s", nam.c_str());
944 template <>
void Converter<DDLBox>::operator()(xml_h element)
const {
946 xml_dim_t
e(element);
947 string nam = e.nameStr();
952 "+ Box: dx=%10.3f [cm] dy=%10.3f [cm] dz=%10.3f [cm]", dx, dy, dz);
957 template <>
void Converter<include_load>::operator()(xml_h element)
const {
958 string fname = element.attr<
string>(_U(ref));
961 doc = xml::DocumentHandler().load( fp.fullPath());
962 printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS : DEBUG,
963 "MyDDCMS",
"+++ Processing the CMS detector description %s", fname.c_str());
964 _option<DDRegistry>()->
includes.emplace_back( doc );
968 template <>
void Converter<include_unload>::operator()(xml_h element)
const {
969 string fname = xml::DocumentHandler::system_path(element);
970 xml::DocumentHolder(xml_elt_t(element).document()).assign(
nullptr);
971 printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS : DEBUG,
972 "MyDDCMS",
"+++ Finished processing %s",fname.c_str());
976 template <>
void Converter<include_constants>::operator()(xml_h element)
const {
977 xml_coll_t(element,
_CMU(ConstantsSection)).for_each(Converter<ConstantsSection>(description,param,optional));
981 template <>
void Converter<DDLAlgorithm>::operator()(xml_h element)
const {
983 xml_dim_t
e(element);
984 string name = e.nameStr();
986 printout(
INFO,
"MyDDCMS",
"+++ Skip disabled algorithms: %s",name.c_str());
996 "MyDDCMS",
"+++ Start executing algorithm %s....",type.c_str());
1001 "MyDDCMS",
"+++ Executed algorithm: %08lX = %s", ret, name.c_str());
1006 DetElement det(PluginService::Create<NamedObject*>(type, &description, _ns.
context, &element, &sd));
1007 if (det.isValid()) {
1009 if ( sd.isValid() ) {
1010 det->flag |= DetElement::Object::HAVE_SENSITIVE_DETECTOR;
1012 if ( seg.isValid() ) {
1013 seg->sensitive =
sd;
1014 seg->detector = det;
1017 if (!det.isValid()) {
1020 except(
"MyDDCMS",
"Failed to execute subdetector creation plugin. " + dbg.missingFactory(type));
1022 description.addDetector(det);
1024 printout(
ERROR,
"MyDDCMS",
"++ FAILED NOT ADDING SUBDETECTOR %08lX = %s",ret, name.c_str());
1029 printout(
ERROR,
"MyDDCMS",
"++ FAILED to convert subdetector: %s: %s", name.c_str(), exc.what());
1033 printout(
ERROR,
"MyDDCMS",
"++ FAILED to convert subdetector: %s: %s", name.c_str(),
"UNKNONW Exception");
1038 template <
class InputIt,
class ForwardIt,
class BinOp>
1040 ForwardIt s_first, ForwardIt s_last,
1043 while( first != last ) {
1044 const auto pos = std::find_first_of( first, last, s_first, s_last );
1045 binary_op( first, pos );
1046 if( pos == last )
break;
1057 cbegin( delims ), cend( delims ),
1060 output.emplace_back(stod(
string(
first,
second )));
1072 cbegin( delims ), cend( delims ),
1083 template <>
void Converter<DDLVector>::operator()( xml_h element )
const {
1087 xml_dim_t
e( element );
1088 string name = e.nameStr();
1089 string type = _ns.
attr<
string>(
e,_U(type));
1090 string nEntries = _ns.
attr<
string>(
e,
_CMU(nEntries));
1091 string val = e.text();
1092 val.erase( remove_if( val.begin(), val.end(), [](
unsigned char x){
return isspace(
x);}), val.end());
1095 "MyDDCMS",
"+++ Vector<%s>: %s[%s]: %s", type.c_str(), name.c_str(),
1096 nEntries.c_str(), val.c_str());
1099 registry->insert( {
name, results } );
1101 for(
auto it : results )
1106 template <>
void Converter<debug>::operator()(xml_h dbg)
const {
1120 template <>
void Converter<DDRegistry>::operator()(xml_h )
const {
1122 DDRegistry* res = _option<DDRegistry>();
1127 "MyDDCMS",
"+++ RESOLVING %ld unknown constants.....",res->unresolvedConst.size());
1128 while ( !res->unresolvedConst.empty() ) {
1129 for(
auto i=res->unresolvedConst.begin();
i!=res->unresolvedConst.end(); ++
i ) {
1130 const string& n = (*i).first;
1132 string&
v = (*i).second;
1134 for(idx=v.find(
'[',0); idx != string::npos; idx = v.find(
'[',idx+1) ) {
1135 idq = v.find(
']',idx+1);
1136 rep = v.substr(idx+1,idq-idx-1);
1137 auto r = res->allConst.find(rep);
1138 if (
r != res->allConst.end() ) {
1139 rep =
"("+(*r).second+
")";
1140 v.replace(idx,idq-idx+1,rep);
1143 if ( v.find(
']') == string::npos ) {
1144 if ( v.find(
"-+") != string::npos || v.find(
"+-") != string::npos ) {
1145 while ( (idx=v.find(
"-+")) != string::npos )
1146 v.replace(idx,2,
"-");
1147 while ( (idx=v.find(
"+-")) != string::npos )
1148 v.replace(idx,2,
"-");
1151 "MyDDCMS",
"+++ [%06ld] ---------- %-40s = %s",
1152 res->unresolvedConst.size()-1,n.c_str(),res->originalConst[
n].c_str());
1153 _ns.addConstantNS(n, v,
"number");
1154 res->unresolvedConst.erase(
i);
1158 if ( ++count > 1000 )
break;
1160 if ( !res->unresolvedConst.empty() ) {
1161 for(
const auto& e : res->unresolvedConst )
1162 printout(
ERROR,
"MyDDCMS",
"+++ Unresolved constant: %-40s = %s.",e.first.c_str(), e.second.c_str());
1163 except(
"MyDDCMS",
"++ FAILED to resolve %ld constant entries:",res->unresolvedConst.size());
1165 res->unresolvedConst.clear();
1166 res->originalConst.clear();
1167 res->allConst.clear();
1170 template <>
void Converter<print_xml_doc>::operator()(xml_h element)
const {
1171 string fname = xml::DocumentHandler::system_path(element);
1172 printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS : DEBUG,
1173 "MyDDCMS",
"+++ Processing data from: %s",fname.c_str());
1180 xml_elt_t dddef(element);
1181 string fname = xml::DocumentHandler::system_path(element);
1182 bool open_geometry = dddef.hasChild(
_CMU(open_geometry));
1183 bool close_geometry = dddef.hasChild(
_CMU(close_geometry));
1185 xml_coll_t(dddef, _U(
debug)).for_each(Converter<debug>(det,&context));
1190 printout(
INFO,
"MyDDCMS",
"+++ Processing the CMS detector description %s",fname.c_str());
1193 Converter<print_xml_doc> print_doc(det,&context);
1196 print_doc((doc=dddef.document()).
root());
1197 xml_coll_t(dddef,
_CMU(DisabledAlgo)).for_each(Converter<disabled_algo>(det,&context,&res));
1198 xml_coll_t(dddef,
_CMU(ConstantsSection)).for_each(Converter<ConstantsSection>(det,&context,&res));
1199 xml_coll_t(dddef,
_CMU(VisSection)).for_each(Converter<vissection>(det,&context));
1200 xml_coll_t(dddef,
_CMU(RotationSection)).for_each(Converter<RotationSection>(det,&context));
1201 xml_coll_t(dddef,
_CMU(MaterialSection)).for_each(Converter<MaterialSection>(det,&context));
1203 xml_coll_t(dddef,
_CMU(IncludeSection)).for_each(
_CMU(Include), Converter<include_load>(det,&context,&res));
1205 for(xml::Document
d : res.includes ) {
1206 print_doc((doc=d).
root());
1207 Converter<include_constants>(det,&context,&res)((doc=d).root());
1210 Converter<DDRegistry>(det,&context,&res)(dddef);
1212 for(xml::Document d : res.includes ) {
1213 print_doc((doc=d).
root());
1214 xml_coll_t(d.root(),
_CMU(MaterialSection)).for_each(Converter<MaterialSection>(det,&context));
1216 if ( open_geometry ) {
1217 context.geo_inited =
true;
1221 for(xml::Document d : res.includes ) {
1222 print_doc((doc=d).
root());
1223 xml_coll_t(d.root(),
_CMU(RotationSection)).for_each(Converter<RotationSection>(det,&context));
1225 for(xml::Document d : res.includes ) {
1226 print_doc((doc=d).
root());
1227 xml_coll_t(d.root(),
_CMU(SolidSection)).for_each(Converter<SolidSection>(det,&context));
1229 for(xml::Document d : res.includes ) {
1230 print_doc((doc=d).
root());
1231 xml_coll_t(d.root(),
_CMU(LogicalPartSection)).for_each(Converter<LogicalPartSection>(det,&context));
1233 for(xml::Document d : res.includes ) {
1234 print_doc((doc=d).
root());
1235 xml_coll_t(d.root(),
_CMU(
Algorithm)).for_each(Converter<DDLAlgorithm>(det,&context));
1237 for(xml::Document d : res.includes ) {
1238 print_doc((doc=d).
root());
1239 xml_coll_t(d.root(),
_CMU(PosPartSection)).for_each(Converter<PosPartSection>(det,&context));
1243 for(xml::Document d : res.includes ) Converter<include_unload>(det,&context,&res)(d.root());
1245 print_doc((doc=dddef.document()).
root());
1247 xml_coll_t(dddef,
_CMU(SolidSection)).for_each(Converter<SolidSection>(det,&context));
1248 xml_coll_t(dddef,
_CMU(LogicalPartSection)).for_each(Converter<LogicalPartSection>(det,&context));
1249 xml_coll_t(dddef,
_CMU(
Algorithm)).for_each(Converter<DDLAlgorithm>(det,&context));
1250 xml_coll_t(dddef,
_CMU(PosPartSection)).for_each(Converter<PosPartSection>(det,&context));
1253 printout(
ERROR,
"MyDDCMS",
"Exception while processing xml source:%s",doc.uri().c_str());
1254 printout(
ERROR,
"MyDDCMS",
"----> %s", e.what());
1259 if ( close_geometry ) {
1262 printout(
INFO,
"DDDefinition",
"+++ Finished processing %s",fname.c_str());
DDLPosPart handles PosPart elements.
DDLSphere processes all Sphere elements.
std::map< std::string, std::string > allConst
ROOT::Math::Plane3D::Vector Vector
DDLVector handles Rotation and ReflectionRotation elements.
dd4hep::Detector * description
Geom::Theta< T > theta() const
DDLEllipticalTube processes all EllipticalTube elements.
dd4hep::Volume addVolume(dd4hep::Volume vol) const
Add rotation matrix to current namespace.
dd4hep::Solid solid(const std::string &name) const
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
dd4hep::Rotation3D makeRotation3D(double thetaX, double phiX, double thetaY, double phiY, double thetaZ, double phiZ)
U second(std::pair< T, U > const &p)
DDLBox processes Box elements.
DDLElementaryMaterial processes ElementaryMaterial elements.
vector< string > splitString(const string &str, const string &delims=",")
std::string realName(const std::string &) const
T attr(xml_elt_t element, const xml_tag_t &name) const
DDLCone processes all Cone elements.
vector< double > splitNumeric(const string &str, const string &delims=",")
constexpr unsigned int hash(const char *str, int h=0)
static void convert_boolean(cms::DDParsingContext *context, xml_h element)
std::set< std::string > disabledAlgs
Namespace of DDCMS conversion namespace.
DDLTubs processes Tubs elements.
std::map< std::string, std::string > originalConst
dd4hep::Solid addSolid(const std::string &name, dd4hep::Solid solid) const
DDLLogicalPart processes LogicalPart elements.
DDParsingContext * context
DDLRotationByAxis handles RotationByAxis elements.
DDLCompositeMaterial processes all CompositeMaterial elements.
std::map< std::string, std::string > unresolvedConst
std::vector< xml::Document > includes
static long load_dddefinition(Detector &det, xml_h element)
Converter for <DDDefinition> tags.
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)