CMS 3D CMS Logo

DDDefinitions2Objects.cc
Go to the documentation of this file.
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 
11 #include "XML/Utilities.h"
18 
19 #include "TGeoManager.h"
20 #include "TGeoMaterial.h"
21 
22 #include <climits>
23 #include <iostream>
24 #include <iomanip>
25 #include <set>
26 #include <map>
27 #include <utility>
28 
29 using namespace std;
30 using namespace dd4hep;
31 using namespace cms;
32 
34 
35 namespace dd4hep {
36 
37  namespace {
38 
39  UInt_t unique_mat_id = 0xAFFEFEED;
40 
41  class disabled_algo;
42  class include_constants;
43  class include_load;
44  class include_unload;
45  class print_xml_doc;
46 
47  class ConstantsSection;
48  class DDLConstant;
49  struct DDRegistry {
50  std::vector<xml::Document> includes;
51  std::map<std::string, std::string> unresolvedConst, allConst, originalConst;
52  };
53 
54  class MaterialSection;
57 
58  class RotationSection;
59  class DDLRotation;
60  class DDLReflectionRotation;
61  class DDLRotationSequence;
62  class DDLRotationByAxis;
63  class DDLTransform3D;
64 
65  class PosPartSection;
66  class DDLPosPart;
67  class DDLDivision;
68 
69  class LogicalPartSection;
70  class DDLLogicalPart;
71 
72  class SolidSection;
73  class DDLExtrudedPolygon;
74  class DDLShapeless;
75  class DDLTrapezoid;
76  class DDLEllipticalTube;
77  class DDLPseudoTrap;
78  class DDLPolyhedra;
79  class DDLPolycone;
80  class DDLTorus;
81  class DDLTrd1;
82  class DDLTrd2;
83  class DDLTruncTubs;
84  class DDLCutTubs;
85  class DDLTubs;
86  class DDLBox;
87  class DDLCone;
88  class DDLSphere;
89  class DDLUnionSolid;
90  class DDLIntersectionSolid;
91  class DDLSubtractionSolid;
92 
93  class DDLAlgorithm;
94  class DDLVector;
95 
96  class SpecParSection;
97  class SpecPar;
98  class PartSelector;
99  class Parameter;
100 
101  class vissection;
102  class vis;
103  class debug;
104  }
105 
107  template <> void Converter<debug>::operator()(xml_h element) const;
108  template <> void Converter<print_xml_doc>::operator()(xml_h element) const;
109  template <> void Converter<disabled_algo>::operator()(xml_h element) const;
110 
112  template <> void Converter<ConstantsSection>::operator()(xml_h element) const;
113  template <> void Converter<DDLConstant>::operator()(xml_h element) const;
114  template <> void Converter<DDRegistry>::operator()(xml_h element) const;
115 
117  template <> void Converter<vissection>::operator()(xml_h element) const;
119  template <> void Converter<vis>::operator()(xml_h element) const;
120 
122  template <> void Converter<MaterialSection>::operator()(xml_h element) const;
123  template <> void Converter<DDLElementaryMaterial>::operator()(xml_h element) const;
124  template <> void Converter<DDLCompositeMaterial>::operator()(xml_h element) const;
125 
127  template <> void Converter<RotationSection>::operator()(xml_h element) const;
129  template <> void Converter<DDLRotation>::operator()(xml_h element) const;
131  template <> void Converter<DDLReflectionRotation>::operator()(xml_h element) const;
133  template <> void Converter<DDLRotationSequence>::operator()(xml_h element) const;
135  template <> void Converter<DDLRotationByAxis>::operator()(xml_h element) const;
136  template <> void Converter<DDLTransform3D>::operator()(xml_h element) const;
137 
139  template <> void Converter<LogicalPartSection>::operator()(xml_h element) const;
140  template <> void Converter<DDLLogicalPart>::operator()(xml_h element) const;
141 
143  template <> void Converter<PosPartSection>::operator()(xml_h element) const;
145  template <> void Converter<DDLPosPart>::operator()(xml_h element) const;
147  template <> void Converter<DDLDivision>::operator()(xml_h element) const;
148 
150  template <> void Converter<SpecParSection>::operator()(xml_h element) const;
151  template <> void Converter<SpecPar>::operator()(xml_h element) const;
152  template <> void Converter<PartSelector>::operator()(xml_h element) const;
153  template <> void Converter<Parameter>::operator()(xml_h element) const;
154 
156  template <> void Converter<SolidSection>::operator()(xml_h element) const;
158  template <> void Converter<DDLUnionSolid>::operator()(xml_h element) const;
160  template <> void Converter<DDLSubtractionSolid>::operator()(xml_h element) const;
162  template <> void Converter<DDLIntersectionSolid>::operator()(xml_h element) const;
164  template <> void Converter<DDLPseudoTrap>::operator()(xml_h element) const;
166  template <> void Converter<DDLExtrudedPolygon>::operator()(xml_h element) const;
168  template <> void Converter<DDLShapeless>::operator()(xml_h element) const;
170  template <> void Converter<DDLTrapezoid>::operator()(xml_h element) const;
172  template <> void Converter<DDLPolycone>::operator()(xml_h element) const;
174  template <> void Converter<DDLPolyhedra>::operator()(xml_h element) const;
176  template <> void Converter<DDLEllipticalTube>::operator()(xml_h element) const;
178  template <> void Converter<DDLTorus>::operator()(xml_h element) const;
180  template <> void Converter<DDLTubs>::operator()(xml_h element) const;
182  template <> void Converter<DDLCutTubs>::operator()(xml_h element) const;
184  template <> void Converter<DDLTruncTubs>::operator()(xml_h element) const;
186  template <> void Converter<DDLSphere>::operator()(xml_h element) const;
188  template <> void Converter<DDLTrd1>::operator()(xml_h element) const;
190  template <> void Converter<DDLTrd2>::operator()(xml_h element) const;
192  template <> void Converter<DDLCone>::operator()(xml_h element) const;
194  template <> void Converter<DDLBox>::operator()(xml_h element) const;
196  template <> void Converter<DDLAlgorithm>::operator()(xml_h element) const;
198  template <> void Converter<DDLVector>::operator()(xml_h element) const;
199 
201  template <> void Converter<include_load>::operator()(xml_h element) const;
203  template <> void Converter<include_unload>::operator()(xml_h element) const;
205  template <> void Converter<include_constants>::operator()(xml_h element) const;
206 }
207 
209 template <> void Converter<ConstantsSection>::operator()( xml_h element ) const {
210  cms::DDNamespace ns( _param<cms::DDParsingContext>(), element );
211  cms::DDParsingContext* const context = ns.context();
212  xml_coll_t( element, DD_CMU( Constant )).for_each( Converter<DDLConstant>( description, context, optional ));
213  xml_coll_t( element, DD_CMU( Vector )).for_each( Converter<DDLVector>( description, context, optional ));
214 }
215 
217 template <> void Converter<vissection>::operator()(xml_h element) const {
218  cms::DDNamespace ns(_param<cms::DDParsingContext>(), element);
219  xml_coll_t( element, DD_CMU(vis)).for_each(Converter<vis>(description,ns.context(),optional));
220 }
221 
223 template <> void Converter<MaterialSection>::operator()(xml_h element) const {
224  cms::DDNamespace ns(_param<cms::DDParsingContext>(), element);
225  xml_coll_t( element, DD_CMU(ElementaryMaterial)).for_each(Converter<DDLElementaryMaterial>(description,ns.context(),optional));
226  xml_coll_t( element, DD_CMU(CompositeMaterial)).for_each(Converter<DDLCompositeMaterial>(description,ns.context(),optional));
227 }
228 
229 template <> void Converter<RotationSection>::operator()(xml_h element) const {
230  cms::DDNamespace ns(_param<cms::DDParsingContext>(), element);
231  xml_coll_t( element, DD_CMU(Rotation)).for_each(Converter<DDLRotation>(description,ns.context(),optional));
232  xml_coll_t( element, DD_CMU(ReflectionRotation)).for_each(Converter<DDLReflectionRotation>(description,ns.context(),optional));
233  xml_coll_t( element, DD_CMU(RotationSequence)).for_each(Converter<DDLRotationSequence>(description,ns.context(),optional));
234  xml_coll_t( element, DD_CMU(RotationByAxis)).for_each(Converter<DDLRotationByAxis>(description,ns.context(),optional));
235 }
236 
237 template <> void Converter<PosPartSection>::operator()( xml_h element ) const {
238  cms::DDNamespace ns( _param<cms::DDParsingContext>(), element );
239  xml_coll_t( element, DD_CMU( Division )).for_each( Converter<DDLDivision>( description, ns.context(), optional ));
240  xml_coll_t( element, DD_CMU( PosPart )).for_each( Converter<DDLPosPart>( description, ns.context(), optional ));
241  xml_coll_t( element, DD_CMU( Algorithm )).for_each( Converter<DDLAlgorithm>( description, ns.context(), optional ));
242 }
243 
244 template <> void Converter<SpecParSection>::operator()( xml_h element ) const {
245  cms::DDNamespace ns( _param<cms::DDParsingContext>(), element );
246  xml_coll_t( element, DD_CMU( SpecPar )).for_each( Converter<SpecPar>( description, ns.context(), optional ));
247 }
248 
249 template <> void Converter<SpecPar>::operator()( xml_h element ) const {
250  cms::DDNamespace ns( _param<cms::DDParsingContext>(), element );
251  xml_coll_t( element, DD_CMU( PartSelector )).for_each( Converter<PartSelector>( description, ns.context(), optional ));
252  xml_coll_t( element, DD_CMU( Parameter )).for_each( Converter<Parameter>( description, ns.context(), optional ));
253 }
254 
256 template <> void Converter<LogicalPartSection>::operator()(xml_h element) const {
257  cms::DDNamespace ns(_param<cms::DDParsingContext>(), element);
258  xml_coll_t( element, DD_CMU(LogicalPart)).for_each(Converter<DDLLogicalPart>(description,ns.context(),optional));
259 }
260 
261 template <> void Converter<disabled_algo>::operator()(xml_h element) const {
262  cms::DDParsingContext* c = _param<cms::DDParsingContext>();
263  c->disabledAlgs.insert( element.attr<string>(_U(name)));
264 }
265 
267 template <> void Converter<SolidSection>::operator()(xml_h element) const {
268  cms::DDNamespace ns(_param<cms::DDParsingContext>(), element);
269  for(xml_coll_t solid(element, _U(star)); solid; ++solid) {
270  string tag = solid.tag();
271  using cms::hash;
272  switch( hash( solid.tag()))
273  {
274  case hash("Box"):
275  Converter<DDLBox>(description,ns.context(),optional)(solid);
276  break;
277  case hash("Polycone"):
278  Converter<DDLPolycone>(description,ns.context(),optional)(solid);
279  break;
280  case hash("Polyhedra"):
281  Converter<DDLPolyhedra>(description,ns.context(),optional)(solid);
282  break;
283  case hash("Tubs"):
284  Converter<DDLTubs>(description,ns.context(),optional)(solid);
285  break;
286  case hash("CutTubs"):
287  Converter<DDLCutTubs>(description,ns.context(),optional)(solid);
288  break;
289  case hash("TruncTubs"):
290  Converter<DDLTruncTubs>(description,ns.context(),optional)(solid);
291  break;
292  case hash("Tube"):
293  Converter<DDLTubs>(description,ns.context(),optional)(solid);
294  break;
295  case hash("Trd1"):
296  Converter<DDLTrd1>(description,ns.context(),optional)(solid);
297  break;
298  case hash("Trd2"):
299  Converter<DDLTrd2>(description,ns.context(),optional)(solid);
300  break;
301  case hash("Cone"):
302  Converter<DDLCone>(description,ns.context(),optional)(solid);
303  break;
304  case hash("Sphere"):
305  Converter<DDLSphere>(description,ns.context(),optional)(solid);
306  break;
307  case hash("EllipticalTube"):
308  Converter<DDLEllipticalTube>(description,ns.context(),optional)(solid);
309  break;
310  case hash("Torus"):
311  Converter<DDLTorus>(description,ns.context(),optional)(solid);
312  break;
313  case hash("PseudoTrap"):
314  Converter<DDLPseudoTrap>(description,ns.context(),optional)(solid);
315  break;
316  case hash("ExtrudedPolygon"):
317  Converter<DDLExtrudedPolygon>(description,ns.context(),optional)(solid);
318  break;
319  case hash("Trapezoid"):
320  Converter<DDLTrapezoid>(description,ns.context(),optional)(solid);
321  break;
322  case hash("UnionSolid"):
323  Converter<DDLUnionSolid>(description,ns.context(),optional)(solid);
324  break;
325  case hash("SubtractionSolid"):
326  Converter<DDLSubtractionSolid>(description,ns.context(),optional)(solid);
327  break;
328  case hash("IntersectionSolid"):
329  Converter<DDLIntersectionSolid>(description,ns.context(),optional)(solid);
330  break;
331  case hash("ShapelessSolid"):
332  Converter<DDLShapeless>(description,ns.context(),optional)(solid);
333  break;
334  default:
335  throw std::runtime_error( "Request to process unknown shape '" + xml_dim_t(solid).nameStr() + "' [" + tag + "]");
336  break;
337  }
338  }
339 }
340 
342 template <> void Converter<DDLConstant>::operator()(xml_h element) const {
343  cms::DDNamespace ns(_param<cms::DDParsingContext>());
344  DDRegistry* res = _option<DDRegistry>();
345  xml_dim_t constant = element;
346  xml_dim_t par = constant.parent();
347  bool eval = par.hasAttr(_U(eval)) ? par.attr<bool>(_U(eval)) : false;
348  string val = constant.valueStr();
349  string nam = constant.nameStr();
350  string real = ns.prepend(nam);
351  string typ = eval ? "number" : "string";
352  size_t idx = val.find('[');
353 
354  if( constant.hasAttr(_U(type)) )
355  typ = constant.typeStr();
356 
357  if( idx == string::npos || typ == "string" ) {
358  try {
359  ns.addConstant( nam, val, typ );
360  res->allConst[real] = val;
361  res->originalConst[real] = val;
362  }
363  catch( const exception& e ) {
364  printout( INFO, "DD4CMS", "++ Unresolved constant: %s = %s [%s]. Try to resolve later. [%s]",
365  real.c_str(), val.c_str(), typ.c_str(), e.what());
366  }
367  return;
368  }
369  // Setup the resolution mechanism in Converter<resolve>
370  while ( idx != string::npos ) {
371  ++idx;
372  size_t idp = val.find(':',idx);
373  size_t idq = val.find(']',idx);
374  if( idp == string::npos || idp > idq )
375  val.insert(idx,ns.name());
376  else if( idp != string::npos && idp < idq )
377  val[idp] = NAMESPACE_SEP;
378  idx = val.find('[',idx);
379  }
380  printout(ns.context()->debug_constants ? ALWAYS : DEBUG,
381  "Constant","Unresolved: %s -> %s",real.c_str(),val.c_str());
382  res->allConst[real] = val;
383  res->originalConst[real] = val;
384  res->unresolvedConst[real] = val;
385 }
386 
395 template <> void Converter<vis>::operator()(xml_h e) const {
396  cms::DDNamespace ns(_param<cms::DDParsingContext>());
397  VisAttr attr(e.attr<string>(_U(name)));
398  float red = e.hasAttr(_U(r)) ? e.attr<float>(_U(r)) : 1.0f;
399  float green = e.hasAttr(_U(g)) ? e.attr<float>(_U(g)) : 1.0f;
400  float blue = e.hasAttr(_U(b)) ? e.attr<float>(_U(b)) : 1.0f;
401 
402  printout(ns.context()->debug_visattr ? ALWAYS : DEBUG, "Compact",
403  "++ Converting VisAttr structure: %-16s. R=%.3f G=%.3f B=%.3f",
404  attr.name(), red, green, blue);
405  attr.setColor(red, green, blue);
406  if(e.hasAttr(_U(alpha)))
407  attr.setAlpha(e.attr<float>(_U(alpha)));
408  if(e.hasAttr(_U(visible)))
409  attr.setVisible(e.attr<bool>(_U(visible)));
410  if(e.hasAttr(_U(lineStyle))) {
411  string ls = e.attr<string>(_U(lineStyle));
412  if(ls == "unbroken")
413  attr.setLineStyle(VisAttr::SOLID);
414  else if(ls == "broken")
415  attr.setLineStyle(VisAttr::DASHED);
416  }
417  else {
418  attr.setLineStyle(VisAttr::SOLID);
419  }
420  if(e.hasAttr(_U(drawingStyle))) {
421  string ds = e.attr<string>(_U(drawingStyle));
422  if(ds == "wireframe")
423  attr.setDrawingStyle(VisAttr::WIREFRAME);
424  else if(ds == "solid")
425  attr.setDrawingStyle(VisAttr::SOLID);
426  }
427  else {
428  attr.setDrawingStyle(VisAttr::SOLID);
429  }
430  if(e.hasAttr(_U(showDaughters)))
431  attr.setShowDaughters(e.attr<bool>(_U(showDaughters)));
432  else
433  attr.setShowDaughters(true);
434  description.addVisAttribute(attr);
435 }
436 
438 template <> void Converter<DDLElementaryMaterial>::operator()(xml_h element) const {
439  cms::DDNamespace ns(_param<cms::DDParsingContext>());
440  xml_dim_t xmat( element);
441  string nam = ns.prepend(xmat.nameStr());
442  TGeoManager& mgr = description.manager();
443  TGeoMaterial* mat = mgr.GetMaterial(nam.c_str());
444  if( nullptr == mat ) {
445  const char* matname = nam.c_str();
446  double density = xmat.density();
447  double atomicNumber = xmat.attr<double>(DD_CMU(atomicNumber));
448  TGeoElementTable* tab = mgr.GetElementTable();
449  TGeoMixture* mix = new TGeoMixture(nam.c_str(), 1, density);
450  TGeoElement* elt = tab->FindElement(xmat.nameStr().c_str());
451 
452  printout(ns.context()->debug_materials ? ALWAYS : DEBUG, "DD4CMS",
453  "+++ Converting material %-48s Density: %.3f.",
454  ('"'+nam+'"').c_str(), density);
455 
456  if( !elt ) {
457  printout(WARNING,"DD4CMS",
458  "+++ Converter<ElementaryMaterial> No element present with name:%s [FAKE IT]",
459  matname);
460  int n = int(atomicNumber/2e0);
461  if( n < 2 ) n = 2;
462  elt = new TGeoElement(xmat.nameStr().c_str(),"CMS element",n,atomicNumber);
463  }
464  if( elt->Z() == 0 ) {
465  int n = int(atomicNumber/2e0);
466  if( n < 2 ) n = 2;
467  elt = new TGeoElement((xmat.nameStr()+"-CMS").c_str(),"CMS element",n,atomicNumber);
468  }
469  mix->AddElement(elt, 1.0);
470  mix->SetRadLen(0e0);
472  TGeoMedium* medium = mgr.GetMedium(matname);
473  if(nullptr == medium) {
474  --unique_mat_id;
475  medium = new TGeoMedium(matname, unique_mat_id, mix);
476  medium->SetTitle("material");
477  medium->SetUniqueID(unique_mat_id);
478  }
479  }
480 }
481 
483 template <> void Converter<DDLCompositeMaterial>::operator()(xml_h element) const {
484  cms::DDNamespace ns(_param<cms::DDParsingContext>());
485  xml_dim_t xmat( element);
486  string nam = ns.prepend(xmat.nameStr());
487  TGeoManager& mgr = description.manager();
488  TGeoMaterial* mat = mgr.GetMaterial(nam.c_str());
489  if( nullptr == mat ) {
490  const char* matname = nam.c_str();
491  double density = xmat.density();
492  xml_coll_t composites(xmat,DD_CMU(MaterialFraction));
493  TGeoMixture* mix = new TGeoMixture(nam.c_str(), composites.size(), density);
494 
495  printout(ns.context()->debug_materials ? ALWAYS : DEBUG, "DD4CMS",
496  "++ Converting material %-48s Density: %.3f.",
497  ('"'+nam+'"').c_str(), density);
498 
499  for( composites.reset(); composites; ++composites ) {
500  xml_dim_t xfrac(composites);
501  xml_dim_t xfrac_mat(xfrac.child(DD_CMU(rMaterial)));
502  double fraction = xfrac.fraction();
503  string fracname = ns.realName(xfrac_mat.nameStr());
504 
505  TGeoMaterial* frac_mat = mgr.GetMaterial(fracname.c_str());
506  if( frac_mat ) {
507  mix->AddElement(frac_mat, fraction);
508  continue;
509  }
510  printout(WARNING,"DD4CMS","+++ Composite material \"%s\" not present!",
511  fracname.c_str());
512  }
513  mix->SetRadLen(0e0);
515  TGeoMedium* medium = mgr.GetMedium(matname);
516  if( nullptr == medium ) {
517  --unique_mat_id;
518  medium = new TGeoMedium(matname, unique_mat_id, mix);
519  medium->SetTitle("material");
520  medium->SetUniqueID(unique_mat_id);
521  }
522  }
523 }
524 
526 template <> void Converter<DDLRotation>::operator()(xml_h element) const {
527  cms::DDParsingContext* context = _param<cms::DDParsingContext>();
528  cms::DDNamespace ns(context);
529  xml_dim_t xrot( element);
530  string nam = xrot.nameStr();
531  double thetaX = xrot.hasAttr(DD_CMU(thetaX)) ? ns.attr<double>(xrot,DD_CMU(thetaX)) : 0e0;
532  double phiX = xrot.hasAttr(DD_CMU(phiX)) ? ns.attr<double>(xrot,DD_CMU(phiX)) : 0e0;
533  double thetaY = xrot.hasAttr(DD_CMU(thetaY)) ? ns.attr<double>(xrot,DD_CMU(thetaY)) : 0e0;
534  double phiY = xrot.hasAttr(DD_CMU(phiY)) ? ns.attr<double>(xrot,DD_CMU(phiY)) : 0e0;
535  double thetaZ = xrot.hasAttr(DD_CMU(thetaZ)) ? ns.attr<double>(xrot,DD_CMU(thetaZ)) : 0e0;
536  double phiZ = xrot.hasAttr(DD_CMU(phiZ)) ? ns.attr<double>(xrot,DD_CMU(phiZ)) : 0e0;
537  Rotation3D rot = makeRotation3D(thetaX, phiX, thetaY, phiY, thetaZ, phiZ);
538  printout(context->debug_rotations ? ALWAYS : DEBUG,
539  "DD4CMS","+++ Adding rotation: %-32s: (theta/phi)[rad] X: %6.3f %6.3f Y: %6.3f %6.3f Z: %6.3f %6.3f",
540  ns.prepend(nam).c_str(),thetaX,phiX,thetaY,phiY,thetaZ,phiZ);
541  ns.addRotation(nam, rot);
542 }
543 
545 template <> void Converter<DDLReflectionRotation>::operator()( xml_h element ) const {
546  cms::DDParsingContext* context = _param<cms::DDParsingContext>();
547  cms::DDNamespace ns( context );
548  xml_dim_t xrot( element );
549  string name = xrot.nameStr();
550  double thetaX = xrot.hasAttr( DD_CMU( thetaX )) ? ns.attr<double>( xrot, DD_CMU( thetaX )) : 0e0;
551  double phiX = xrot.hasAttr( DD_CMU( phiX )) ? ns.attr<double>( xrot, DD_CMU( phiX )) : 0e0;
552  double thetaY = xrot.hasAttr( DD_CMU( thetaY )) ? ns.attr<double>( xrot, DD_CMU( thetaY )) : 0e0;
553  double phiY = xrot.hasAttr( DD_CMU( phiY )) ? ns.attr<double>( xrot, DD_CMU( phiY )) : 0e0;
554  double thetaZ = xrot.hasAttr( DD_CMU( thetaZ )) ? ns.attr<double>( xrot, DD_CMU( thetaZ )) : 0e0;
555  double phiZ = xrot.hasAttr( DD_CMU( phiZ )) ? ns.attr<double>( xrot, DD_CMU( phiZ )) : 0e0;
556  printout( context->debug_rotations ? ALWAYS : DEBUG,
557  "DD4CMS","+++ Adding reflection rotation: %-32s: (theta/phi)[rad] X: %6.3f %6.3f Y: %6.3f %6.3f Z: %6.3f %6.3f",
558  ns.prepend( name ).c_str(), thetaX, phiX, thetaY, phiY, thetaZ, phiZ );
559  Rotation3D rot = makeRotReflect( thetaX, phiX, thetaY, phiY, thetaZ, phiZ );
560  ns.addRotation( name, rot );
561 }
562 
564 template <> void Converter<DDLRotationSequence>::operator()(xml_h element) const {
565  cms::DDParsingContext* context = _param<cms::DDParsingContext>();
566  cms::DDNamespace ns(context);
567  xml_dim_t xrot( element);
568  string nam = xrot.nameStr();
569  Rotation3D rot;
570  xml_coll_t rotations(xrot,DD_CMU(RotationByAxis));
571  for( rotations.reset(); rotations; ++rotations ) {
572  string axis = ns.attr<string>(rotations,DD_CMU(axis));
573  double angle = ns.attr<double>(rotations,_U(angle));
574  rot = makeRotation3D( rot, axis, angle );
575  printout(context->debug_rotations ? ALWAYS : DEBUG,
576  "DD4CMS","+ Adding rotation to: %-29s: (axis/angle)[rad] Axis: %s Angle: %6.3f",
577  nam.c_str(), axis.c_str(), angle);
578  }
579  double xx, xy, xz;
580  double yx, yy, yz;
581  double zx, zy, zz;
582  rot.GetComponents(xx,xy,xz,yx,yy,yz,zx,zy,zz);
583  printout(context->debug_rotations ? ALWAYS : DEBUG,
584  "DD4CMS","+++ Adding rotation sequence: %-23s: %6.3f %6.3f %6.3f, %6.3f %6.3f %6.3f, %6.3f %6.3f %6.3f",
585  ns.prepend(nam).c_str(), xx, xy, xz, yx, yy, yz, zx, zy, zz);
586  ns.addRotation(nam, rot);
587 }
588 
590 template <> void Converter<DDLRotationByAxis>::operator()(xml_h element) const {
591  cms::DDParsingContext* context = _param<cms::DDParsingContext>();
592  cms::DDNamespace ns(context);
593  xml_dim_t xrot( element);
594  xml_dim_t par(xrot.parent());
595  if( xrot.hasAttr(_U(name))) {
596  string nam = xrot.nameStr();// + string("Rotation"); // xrot.hasAttr(_U(name)) ? xrot.nameStr() : par.nameStr();
597  string axis = ns.attr<string>(xrot,DD_CMU(axis));
598  double angle = ns.attr<double>(xrot,_U(angle));
599  Rotation3D rot;
600  rot = makeRotation3D( rot, axis, angle );
601  printout(context->debug_rotations ? ALWAYS : DEBUG,
602  "DD4CMS","+++ Adding rotation: %-32s: (axis/angle)[rad] Axis: %s Angle: %6.3f",
603  ns.prepend(nam).c_str(), axis.c_str(), angle);
604  ns.addRotation(nam, rot);
605  }
606 }
607 
609 template <> void Converter<DDLLogicalPart>::operator()(xml_h element) const {
610  cms::DDNamespace ns(_param<cms::DDParsingContext>());
611  xml_dim_t e(element);
612  string sol = e.child(DD_CMU(rSolid)).attr<string>(_U(name));
613  string mat = e.child(DD_CMU(rMaterial)).attr<string>(_U(name));
614  ns.addVolume(Volume(e.nameStr(), ns.solid(sol), ns.material(mat)));
615 }
616 
618 template <> void Converter<DDLTransform3D>::operator()( xml_h element ) const {
619  cms::DDNamespace ns( _param<cms::DDParsingContext>());
620  Transform3D* tr = _option<Transform3D>();
621  xml_dim_t e(element);
622  xml_dim_t translation = e.child( DD_CMU( Translation ), false );
623  xml_dim_t rotation = e.child( DD_CMU( Rotation ), false );
624  xml_dim_t refRotation = e.child( DD_CMU( rRotation ), false );
625  Position pos;
626  Rotation3D rot;
627 
628  if( translation.ptr()) {
629  double x = ns.attr<double>( translation, _U( x ));
630  double y = ns.attr<double>( translation, _U( y ));
631  double z = ns.attr<double>( translation, _U( z ));
632  pos = Position(x,y,z);
633  }
634  if( rotation.ptr()) {
635  double x = ns.attr<double>( rotation, _U( x ));
636  double y = ns.attr<double>( rotation, _U( y ));
637  double z = ns.attr<double>( rotation, _U( z ));
638  rot = RotationZYX(z,y,x);
639  }
640  else if( refRotation.ptr()) {
641  string rotName = refRotation.nameStr();
642  if( strchr( rotName.c_str(), NAMESPACE_SEP ) == nullptr )
643  rotName = ns.name() + rotName;
644 
645  rot = ns.rotation( rotName );
646  }
647  *tr = Transform3D( rot, pos );
648 }
649 
651 template <> void Converter<DDLPosPart>::operator()( xml_h element ) const {
652  cms::DDNamespace ns( _param<cms::DDParsingContext>()); //, element, true );
653  xml_dim_t e( element );
654  int copy = e.attr<int>( DD_CMU( copyNumber ));
655  string parentName = ns.attr<string>( e.child( DD_CMU( rParent )), _U( name ));
656  string childName = ns.attr<string>( e.child( DD_CMU( rChild )), _U( name ));
657  Volume parent = ns.volume( parentName );
658 
659  if( strchr( childName.c_str(), NAMESPACE_SEP ) == nullptr )
660  childName = ns.name() + childName;
661  Volume child = ns.volume( childName, false );
662 
663  printout( ns.context()->debug_placements ? ALWAYS : DEBUG, "DD4CMS",
664  "+++ %s Parent: %-24s [%s] Child: %-32s [%s] copy:%d",
665  e.tag().c_str(),
666  parentName.c_str(), parent.isValid() ? "VALID" : "INVALID",
667  childName.c_str(), child.isValid() ? "VALID" : "INVALID",
668  copy );
669 
670  PlacedVolume pv;
671  if( child.isValid()) {
672  Transform3D transform;
673  Converter<DDLTransform3D>( description, param, &transform )( element );
674  pv = parent.placeVolume( child, copy, transform );
675  }
676  if( !pv.isValid()) {
677  printout( ERROR,"DD4CMS","+++ Placement FAILED! Parent:%s Child:%s Valid:%s",
678  parent.name(), childName.c_str(), yes_no( child.isValid()));
679  }
680 }
681 
683 template <> void Converter<PartSelector>::operator()( xml_h element ) const {
684  cms::DDNamespace ns( _param<cms::DDParsingContext>()); //, element, true );
685  xml_dim_t e( element );
686  xml_dim_t specPar = e.parent();
687  string specParName = specPar.attr<string>( _U( name ));
688  string path = e.attr<string>( DD_CMU( path ));
689 
690  printout(ns.context()->debug_specpars ? ALWAYS : DEBUG, "DD4CMS",
691  "+++ PartSelector for %s path: %s", specParName.c_str(), path.c_str());
692 }
693 
695 template <> void Converter<Parameter>::operator()( xml_h element ) const {
696  cms::DDNamespace ns( _param<cms::DDParsingContext>()); //, element, true );
697  xml_dim_t e( element );
698  string name = e.nameStr();
699  string value = e.attr<string>( DD_CMU( value ));
700  bool eval = e.hasAttr( _U( eval )) ? e.attr<bool>( _U( eval )) : false;
701  string type = eval ? "number" : "string";
702 
703  printout(ns.context()->debug_specpars ? ALWAYS : DEBUG, "DD4CMS",
704  "+++ Parameter: %s value %s is %s", name.c_str(), value.c_str(), type.c_str());
705 }
706 
707 template <typename TYPE>
708 static void convert_boolean(cms::DDParsingContext* context, xml_h element) {
709  cms::DDNamespace ns(context);
710  xml_dim_t e(element);
711  string nam = e.nameStr();
712  Solid solids[2];
713  Solid boolean;
714  int cnt = 0;
715 
716  if( e.hasChild(DD_CMU(rSolid)) ) { // Old version
717  for(xml_coll_t c(element, DD_CMU(rSolid)); cnt<2 && c; ++c, ++cnt)
718  solids[cnt] = ns.solid(c.attr<string>(_U(name)));
719  }
720  else {
721  if( (solids[0] = ns.solid(e.attr<string>(DD_CMU(firstSolid)))).isValid() ) ++cnt;
722  if( (solids[1] = ns.solid(e.attr<string>(DD_CMU(secondSolid)))).isValid() ) ++cnt;
723  }
724  if( cnt != 2 ) {
725  except("DD4CMS","+++ Failed to create boolean solid %s. Found only %d parts.",nam.c_str(), cnt);
726  }
727  printout(ns.context()->debug_placements ? ALWAYS : DEBUG, "DD4CMS",
728  "+++ BooleanSolid: %s Left: %-32s Right: %-32s",
729  nam.c_str(), solids[0]->GetName(), solids[1]->GetName());
730 
731  if( solids[0].isValid() && solids[1].isValid() ) {
732  Transform3D trafo;
733  Converter<DDLTransform3D>(*context->description,context,&trafo)(element);
734  boolean = TYPE(solids[0],solids[1],trafo);
735  }
736  if( !boolean.isValid() )
737  except("DD4CMS","+++ FAILED to construct subtraction solid: %s",nam.c_str());
738  ns.addSolid(nam,boolean);
739 }
740 
742 template <> void Converter<DDLUnionSolid>::operator()(xml_h element) const {
743  convert_boolean<UnionSolid>(_param<cms::DDParsingContext>(),element);
744 }
745 
747 template <> void Converter<DDLSubtractionSolid>::operator()(xml_h element) const {
748  convert_boolean<SubtractionSolid>(_param<cms::DDParsingContext>(),element);
749 }
750 
752 template <> void Converter<DDLIntersectionSolid>::operator()(xml_h element) const {
753  convert_boolean<IntersectionSolid>(_param<cms::DDParsingContext>(),element);
754 }
755 
757 template <> void Converter<DDLPolycone>::operator()(xml_h element) const {
758  cms::DDNamespace ns(_param<cms::DDParsingContext>());
759  xml_dim_t e(element);
760  string nam = e.nameStr();
761  double startPhi = ns.attr<double>( e, DD_CMU(startPhi));
762  double deltaPhi = ns.attr<double>( e, DD_CMU(deltaPhi));
763  vector<double> z, rmin, rmax, r;
764 
765  for(xml_coll_t rzpoint( element, DD_CMU(RZPoint)); rzpoint; ++rzpoint) {
766  z.emplace_back(ns.attr<double>(rzpoint,_U(z)));
767  r.emplace_back(ns.attr<double>(rzpoint,_U(r)));
768  }
769  if( z.empty()) {
770  for(xml_coll_t zplane(element, DD_CMU(ZSection)); zplane; ++zplane) {
771  rmin.emplace_back(ns.attr<double>(zplane,DD_CMU(rMin)));
772  rmax.emplace_back(ns.attr<double>(zplane,DD_CMU(rMax)));
773  z.emplace_back(ns.attr<double>(zplane,_U(z)));
774  }
775  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG, "DD4CMS",
776  "+ Polycone: startPhi=%10.3f [rad] deltaPhi=%10.3f [rad] %4ld z-planes",
777  startPhi, deltaPhi, z.size());
778  ns.addSolid(nam, Polycone(startPhi,deltaPhi,rmin,rmax,z));
779  }
780  else {
781  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG, "DD4CMS",
782  "+ Polycone: startPhi=%10.3f [rad] deltaPhi=%10.3f [rad] %4ld z-planes and %4ld radii",
783  startPhi, deltaPhi, z.size(), r.size());
784  ns.addSolid(nam, Polycone(startPhi,deltaPhi,r,z));
785  }
786 }
787 
789 template <> void Converter<DDLExtrudedPolygon>::operator()(xml_h element) const {
790  cms::DDNamespace ns(_param<cms::DDParsingContext>());
791  xml_dim_t e(element);
792  string nam = e.nameStr();
793  vector<double> pt_x, pt_y, sec_x, sec_y, sec_z, sec_scale;
794 
795  for(xml_coll_t sec(element, DD_CMU(ZXYSection)); sec; ++sec) {
796  sec_z.emplace_back(ns.attr<double>(sec,_U(z)));
797  sec_x.emplace_back(ns.attr<double>(sec,_U(x)));
798  sec_y.emplace_back(ns.attr<double>(sec,_U(y)));
799  sec_scale.emplace_back(ns.attr<double>(sec,DD_CMU(scale),1.0));
800  }
801  for(xml_coll_t pt( element, DD_CMU(XYPoint)); pt; ++pt) {
802  pt_x.emplace_back(ns.attr<double>(pt,_U(x)));
803  pt_y.emplace_back(ns.attr<double>(pt,_U(y)));
804  }
805  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG, "DD4CMS",
806  "+ ExtrudedPolygon: %4ld points %4ld zxy sections",
807  pt_x.size(), sec_z.size());
808  ns.addSolid(nam,ExtrudedPolygon(pt_x,pt_y,sec_z,sec_x,sec_y,sec_scale));
809 }
810 
812 template <> void Converter<DDLPolyhedra>::operator()(xml_h element) const {
813  cms::DDNamespace ns(_param<cms::DDParsingContext>());
814  xml_dim_t e(element);
815  string nam = e.nameStr();
816  double numSide = ns.attr<int>( e, DD_CMU(numSide));
817  double startPhi = ns.attr<double>( e, DD_CMU(startPhi));
818  double deltaPhi = ns.attr<double>( e, DD_CMU(deltaPhi));
819  vector<double> z, rmin, rmax;
820 
821  for(xml_coll_t zplane(element, DD_CMU(RZPoint)); zplane; ++zplane) {
822  rmin.emplace_back(0.0);
823  rmax.emplace_back(ns.attr<double>(zplane,_U(r)));
824  z.emplace_back(ns.attr<double>(zplane,_U(z)));
825  }
826  for(xml_coll_t zplane(element, DD_CMU(ZSection)); zplane; ++zplane) {
827  rmin.emplace_back(ns.attr<double>(zplane,DD_CMU(rMin)));
828  rmax.emplace_back(ns.attr<double>(zplane,DD_CMU(rMax)));
829  z.emplace_back(ns.attr<double>(zplane,_U(z)));
830  }
831  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG, "DD4CMS",
832  "+ Polyhedra:startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] %4d sides %4ld z-planes",
833  startPhi, deltaPhi, numSide, z.size());
834  ns.addSolid(nam, Polyhedra(numSide,startPhi,deltaPhi,z,rmin,rmax));
835 }
836 
838 template <> void Converter<DDLSphere>::operator()(xml_h element) const {
839  cms::DDNamespace ns(_param<cms::DDParsingContext>());
840  xml_dim_t e(element);
841  string nam = e.nameStr();
842  double rinner = ns.attr<double>( e, DD_CMU(innerRadius));
843  double router = ns.attr<double>( e, DD_CMU(outerRadius));
844  double startPhi = ns.attr<double>( e, DD_CMU(startPhi));
845  double deltaPhi = ns.attr<double>( e, DD_CMU(deltaPhi));
846  double startTheta = ns.attr<double>( e, DD_CMU(startTheta));
847  double deltaTheta = ns.attr<double>( e, DD_CMU(deltaTheta));
848  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG, "DD4CMS",
849  "+ Sphere: r_inner=%8.3f [cm] r_outer=%8.3f [cm]"
850  " startPhi=%8.3f [rad] deltaPhi=%8.3f startTheta=%8.3f delteTheta=%8.3f [rad]",
851  rinner, router, startPhi, deltaPhi, startTheta, deltaTheta);
852  ns.addSolid(nam, Sphere(rinner, router, startTheta, deltaTheta, startPhi, deltaPhi));
853 }
854 
856 template <> void Converter<DDLTorus>::operator()(xml_h element) const {
857  cms::DDNamespace ns(_param<cms::DDParsingContext>());
858  xml_dim_t e(element);
859  string nam = e.nameStr();
860  double r = ns.attr<double>( e, DD_CMU(torusRadius));
861  double rinner = ns.attr<double>( e, DD_CMU(innerRadius));
862  double router = ns.attr<double>( e, DD_CMU(outerRadius));
863  double startPhi = ns.attr<double>( e, DD_CMU(startPhi));
864  double deltaPhi = ns.attr<double>( e, DD_CMU(deltaPhi));
865  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG, "DD4CMS",
866  "+ Torus: r=%10.3f [cm] r_inner=%10.3f [cm] r_outer=%10.3f [cm]"
867  " startPhi=%10.3f [rad] deltaPhi=%10.3f [rad]",
868  r, rinner, router, startPhi, deltaPhi);
869  ns.addSolid(nam, Torus(r, rinner, router, startPhi, deltaPhi));
870 }
871 
873 template <> void Converter<DDLPseudoTrap>::operator()(xml_h element) const {
874  cms::DDNamespace ns(_param<cms::DDParsingContext>());
875  xml_dim_t e(element);
876  string nam = e.nameStr();
877  double dx1 = ns.attr<double>( e, DD_CMU(dx1));
878  double dy1 = ns.attr<double>( e, DD_CMU(dy1));
879  double dx2 = ns.attr<double>( e, DD_CMU(dx2));
880  double dy2 = ns.attr<double>( e, DD_CMU(dy2));
881  double dz = ns.attr<double>(e,_U(dz));
882  double r = ns.attr<double>(e,_U(radius));
883  bool atMinusZ = ns.attr<bool> ( e, DD_CMU(atMinusZ));
884  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG, "DD4CMS",
885  "+ Pseudotrap: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2=%.3f dy2=%.3f radius:%.3f atMinusZ:%s",
886  dz, dx1, dy1, dx2, dy2, r, yes_no(atMinusZ));
887  ns.addSolid(nam, PseudoTrap(dx1, dx2, dy1, dy2, dz, r, atMinusZ));
888 }
889 
891 template <> void Converter<DDLTrapezoid>::operator()(xml_h element) const {
892  cms::DDNamespace ns(_param<cms::DDParsingContext>());
893  xml_dim_t e(element);
894  string nam = e.nameStr();
895  double dz = ns.attr<double>(e,_U(dz));
896  double alp1 = ns.attr<double>( e, DD_CMU(alp1));
897  double bl1 = ns.attr<double>( e, DD_CMU(bl1));
898  double tl1 = ns.attr<double>( e, DD_CMU(tl1));
899  double h1 = ns.attr<double>( e, DD_CMU(h1));
900  double alp2 = ns.attr<double>( e, DD_CMU(alp2));
901  double bl2 = ns.attr<double>( e, DD_CMU(bl2));
902  double tl2 = ns.attr<double>( e, DD_CMU(tl2));
903  double h2 = ns.attr<double>( e, DD_CMU(h2));
904  double phi = ns.attr<double>(e,_U(phi),0.0);
905  double theta = ns.attr<double>(e,_U(theta),0.0);
906 
907  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG, "DD4CMS",
908  "+ Trapezoid: dz=%10.3f [cm] alp1:%.3f bl1=%.3f tl1=%.3f alp2=%.3f bl2=%.3f tl2=%.3f h2=%.3f phi=%.3f theta=%.3f",
909  dz, alp1, bl1, tl1, h1, alp2, bl2, tl2, h2, phi, theta);
910  ns.addSolid( nam, Trap( dz, theta, phi, h1, bl1, tl1, alp1, h2, bl2, tl2, alp2 ));
911 }
912 
914 template <> void Converter<DDLTrd1>::operator()(xml_h element) const {
915  cms::DDNamespace ns( _param<cms::DDParsingContext>());
916  xml_dim_t e( element );
917  string nam = e.nameStr();
918  double dx1 = ns.attr<double>( e, DD_CMU( dx1 ));
919  double dy1 = ns.attr<double>( e, DD_CMU( dy1 ));
920  double dx2 = ns.attr<double>( e, DD_CMU( dx2 ), 0.0 );
921  double dy2 = ns.attr<double>( e, DD_CMU( dy2 ), dy1 );
922  assert( dy1 == dy2 );
923  double dz = ns.attr<double>( e, DD_CMU( dz ));
924  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG, "DD4CMS",
925  "+ Trd1: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
926  dz, dx1, dy1, dx2, dy2);
927  ns.addSolid( nam, Trd1( dx1, dx2, dy1, dz ));
928 }
929 
931 template <> void Converter<DDLTrd2>::operator()(xml_h element) const {
932  cms::DDNamespace ns( _param<cms::DDParsingContext>());
933  xml_dim_t e( element );
934  string nam = e.nameStr();
935  double dx1 = ns.attr<double>( e, DD_CMU( dx1 ));
936  double dy1 = ns.attr<double>( e, DD_CMU( dy1 ));
937  double dx2 = ns.attr<double>( e, DD_CMU( dx2 ), 0.0 );
938  double dy2 = ns.attr<double>( e, DD_CMU( dy2 ), dy1 );
939  double dz = ns.attr<double>( e, DD_CMU( dz ));
940  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG, "DD4CMS",
941  "+ Trd1: dz=%8.3f [cm] dx1:%.3f dy1:%.3f dx2:%.3f dy2:%.3f",
942  dz, dx1, dy1, dx2, dy2);
943  ns.addSolid( nam, Trd2( dx1, dx2, dy1, dy2, dz ));
944 }
945 
947 template <> void Converter<DDLTubs>::operator()(xml_h element) const {
948  cms::DDNamespace ns(_param<cms::DDParsingContext>());
949  xml_dim_t e(element);
950  string nam = e.nameStr();
951  double dz = ns.attr<double>( e, DD_CMU(dz));
952  double rmin = ns.attr<double>( e, DD_CMU(rMin));
953  double rmax = ns.attr<double>( e, DD_CMU(rMax));
954  double startPhi = ns.attr<double>( e, DD_CMU(startPhi),0.0);
955  double deltaPhi = ns.attr<double>( e, DD_CMU(deltaPhi),2*M_PI);
956  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG, "DD4CMS",
957  "+ Tubs: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
958  " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]", dz, rmin, rmax, startPhi, deltaPhi );
959  ns.addSolid(nam, Tube( rmin, rmax, dz, startPhi, startPhi + deltaPhi ));
960 }
961 
963 template <> void Converter<DDLCutTubs>::operator()(xml_h element) const {
964  cms::DDNamespace ns(_param<cms::DDParsingContext>());
965  xml_dim_t e(element);
966  string nam = e.nameStr();
967  double dz = ns.attr<double>( e, DD_CMU(dz));
968  double rmin = ns.attr<double>( e, DD_CMU(rMin));
969  double rmax = ns.attr<double>( e, DD_CMU(rMax));
970  double startPhi = ns.attr<double>( e, DD_CMU(startPhi));
971  double deltaPhi = ns.attr<double>( e, DD_CMU(deltaPhi));
972  double lx = ns.attr<double>( e, DD_CMU(lx));
973  double ly = ns.attr<double>( e, DD_CMU(ly));
974  double lz = ns.attr<double>( e, DD_CMU(lz));
975  double tx = ns.attr<double>( e, DD_CMU(tx));
976  double ty = ns.attr<double>( e, DD_CMU(ty));
977  double tz = ns.attr<double>( e, DD_CMU(tz));
978  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG, "DD4CMS",
979  "+ CutTube: dz=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
980  " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]...",
981  dz, rmin, rmax, startPhi, deltaPhi);
982  ns.addSolid(nam, CutTube(rmin,rmax,dz,startPhi,deltaPhi,lx,ly,lz,tx,ty,tz));
983 }
984 
986 template <> void Converter<DDLTruncTubs>::operator()(xml_h element) const {
987  cms::DDNamespace ns(_param<cms::DDParsingContext>());
988  xml_dim_t e(element);
989  string nam = e.nameStr();
990  double zhalf = ns.attr<double>( e, DD_CMU(zHalf));
991  double rmin = ns.attr<double>( e, DD_CMU(rMin));
992  double rmax = ns.attr<double>( e, DD_CMU(rMax));
993  double startPhi = ns.attr<double>( e, DD_CMU(startPhi));
994  double deltaPhi = ns.attr<double>( e, DD_CMU(deltaPhi));
995  double cutAtStart = ns.attr<double>( e, DD_CMU(cutAtStart));
996  double cutAtDelta = ns.attr<double>( e, DD_CMU(cutAtDelta));
997  bool cutInside = ns.attr<bool>( e, DD_CMU(cutInside));
998  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG, "DD4CMS",
999  "+ TruncTube:zHalf=%8.3f [cm] rmin=%8.3f [cm] rmax=%8.3f [cm]"
1000  " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad] atStart=%8.3f [cm] atDelta=%8.3f [cm] inside:%s",
1001  zhalf, rmin, rmax, startPhi, deltaPhi, cutAtStart, cutAtDelta, yes_no(cutInside));
1002  ns.addSolid(nam, TruncatedTube(zhalf,rmin,rmax,startPhi,deltaPhi,cutAtStart,cutAtDelta,cutInside));
1003 }
1004 
1006 template <> void Converter<DDLEllipticalTube>::operator()(xml_h element) const {
1007  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1008  xml_dim_t e(element);
1009  string nam = e.nameStr();
1010  double dx = ns.attr<double>( e, DD_CMU(xSemiAxis));
1011  double dy = ns.attr<double>( e, DD_CMU(ySemiAxis));
1012  double dz = ns.attr<double>( e, DD_CMU(zHeight));
1013  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG, "DD4CMS",
1014  "+ EllipticalTube xSemiAxis=%8.3f [cm] ySemiAxis=%8.3f [cm] zHeight=%8.3f [cm]",dx,dy,dz);
1015  ns.addSolid(nam, EllipticalTube(dx,dy,dz));
1016 }
1017 
1019 template <> void Converter<DDLCone>::operator()(xml_h element) const {
1020  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1021  xml_dim_t e(element);
1022  string nam = e.nameStr();
1023  double dz = ns.attr<double>( e, DD_CMU(dz));
1024  double rmin1 = ns.attr<double>( e, DD_CMU(rMin1));
1025  double rmin2 = ns.attr<double>( e, DD_CMU(rMin2));
1026  double rmax1 = ns.attr<double>( e, DD_CMU(rMax1));
1027  double rmax2 = ns.attr<double>( e, DD_CMU(rMax2));
1028  double startPhi = ns.attr<double>( e, DD_CMU(startPhi));
1029  double deltaPhi = ns.attr<double>( e, DD_CMU(deltaPhi));
1030  double phi2 = startPhi + deltaPhi;
1031  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG, "DD4CMS",
1032  "+ Cone: dz=%8.3f [cm]"
1033  " rmin1=%8.3f [cm] rmax1=%8.3f [cm]"
1034  " rmin2=%8.3f [cm] rmax2=%8.3f [cm]"
1035  " startPhi=%8.3f [rad] deltaPhi=%8.3f [rad]",
1036  dz, rmin1, rmax1, rmin2, rmax2, startPhi, deltaPhi);
1037  ns.addSolid(nam, ConeSegment(dz,rmin1,rmax1,rmin2,rmax2,startPhi,phi2));
1038 }
1039 
1041 template <> void Converter<DDLShapeless>::operator()(xml_h element) const {
1042  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1043  xml_dim_t e(element);
1044  string nam = e.nameStr();
1045  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG, "DD4CMS",
1046  "+ Shapeless: THIS ONE CAN ONLY BE USED AT THE VOLUME LEVEL -> Assembly%s", nam.c_str());
1047  ns.addSolid(nam, Box(1,1,1));
1048 }
1049 
1051 template <> void Converter<DDLBox>::operator()(xml_h element) const {
1052  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1053  xml_dim_t e(element);
1054  string nam = e.nameStr();
1055  double dx = ns.attr<double>( e, DD_CMU(dx));
1056  double dy = ns.attr<double>( e, DD_CMU(dy));
1057  double dz = ns.attr<double>( e, DD_CMU(dz));
1058  printout(ns.context()->debug_shapes ? ALWAYS : DEBUG, "DD4CMS",
1059  "+ Box: dx=%10.3f [cm] dy=%10.3f [cm] dz=%10.3f [cm]", dx, dy, dz);
1060  ns.addSolid(nam, Box(dx,dy,dz));
1061 }
1062 
1064 template <> void Converter<include_load>::operator()(xml_h element) const {
1065  string fname = element.attr<string>(_U(ref));
1066  edm::FileInPath fp( fname );
1067  xml::Document doc;
1068  doc = xml::DocumentHandler().load( fp.fullPath());
1069  printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS : DEBUG,
1070  "DD4CMS","+++ Processing the CMS detector description %s", fname.c_str());
1071  _option<DDRegistry>()->includes.emplace_back( doc );
1072 }
1073 
1075 template <> void Converter<include_unload>::operator()(xml_h element) const {
1076  string fname = xml::DocumentHandler::system_path(element);
1077  xml::DocumentHolder(xml_elt_t( element).document()).assign(nullptr);
1078  printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS : DEBUG,
1079  "DD4CMS","+++ Finished processing %s",fname.c_str());
1080 }
1081 
1083 template <> void Converter<include_constants>::operator()(xml_h element) const {
1084  xml_coll_t( element, DD_CMU(ConstantsSection)).for_each(Converter<ConstantsSection>(description,param,optional));
1085 }
1086 
1087 namespace {
1088 
1089  // The meaning of the axis index is the following:
1090  // for all volumes having shapes like box, trd1, trd2, trap, gtra or para - 1,2,3 means X,Y,Z;
1091  // for tube, tubs, cone, cons - 1 means Rxy, 2 means phi and 3 means Z;
1092  // for pcon and pgon - 2 means phi and 3 means Z;
1093  // for spheres 1 means R and 2 means phi.
1094 
1095 enum class DDAxes {x = 1, y = 2, z = 3, rho = 1, phi = 2, undefined};
1096 std::map<std::string, DDAxes> axesmap {{"x", DDAxes::x },
1097  {"y", DDAxes::y},
1098  {"z", DDAxes::z},
1099  {"rho", DDAxes::rho},
1100  {"phi", DDAxes::phi},
1101  {"undefined", DDAxes::undefined }};
1102 }
1103 
1105 template <> void Converter<DDLDivision>::operator()( xml_h element ) const {
1106  cms::DDNamespace ns( _param<cms::DDParsingContext>(), element );
1107  xml_dim_t e( element );
1108  string childName = e.nameStr();
1109  if( strchr( childName.c_str(), NAMESPACE_SEP ) == nullptr )
1110  childName = ns.name() + childName;
1111 
1112  string parentName = ns.attr<string>( e, DD_CMU( parent ));
1113  if( strchr( parentName.c_str(), NAMESPACE_SEP ) == nullptr )
1114  parentName = ns.name() + parentName;
1115  string axis = ns.attr<string>( e, DD_CMU( axis ));
1116 
1117  // If you divide a tube of 360 degrees the offset displaces
1118  // the starting angle, but you still fill the 360 degrees
1119  double offset = e.hasAttr( DD_CMU( offset )) ? ns.attr<double>( e, DD_CMU( offset )) : 0e0;
1120  double width = e.hasAttr( DD_CMU( width )) ? ns.attr<double>( e, DD_CMU( width )) : 0e0;
1121  int nReplicas = e.hasAttr( DD_CMU( nReplicas )) ? ns.attr<int>( e, DD_CMU( nReplicas )) : 0;
1122 
1123  printout( ns.context()->debug_placements ? ALWAYS : DEBUG,
1124  "DD4CMS","+++ Start executing Division of %s along %s (%d) with offset %6.3f and %6.3f to produce %s....",
1125  parentName.c_str(), axis.c_str(), axesmap[axis], offset, width, childName.c_str());
1126 
1127  Volume parent = ns.volume( parentName );
1128 
1129  const TGeoShape* shape = parent.solid();
1130  TClass* cl = shape->IsA();
1131  if( cl == TGeoTubeSeg::Class()) {
1132  const TGeoTubeSeg* sh = ( const TGeoTubeSeg* )shape;
1133  double widthInDeg = ConvertTo( width, deg );
1134  double startInDeg = ConvertTo( offset, deg );
1135  int numCopies = ( int )(( sh->GetPhi2() - sh->GetPhi1())/ widthInDeg );
1136  printout( ns.context()->debug_placements ? ALWAYS : DEBUG,
1137  "DD4CMS","+++ ...divide %s along %s (%d) with offset %6.3f deg and %6.3f deg to produce %d copies",
1138  parent.solid().type(), axis.c_str(), axesmap[axis], startInDeg, widthInDeg, numCopies );
1139  Volume child = parent.divide( childName, static_cast<int>( axesmap[axis]),
1140  numCopies, startInDeg, widthInDeg );
1141 
1142  ns.context()->volumes[childName] = child;
1143 
1144  printout( ns.context()->debug_placements ? ALWAYS : DEBUG, "DD4CMS",
1145  "+++ %s Parent: %-24s [%s] Child: %-32s [%s] is multivolume [%s]",
1146  e.tag().c_str(),
1147  parentName.c_str(), parent.isValid() ? "VALID" : "INVALID",
1148  child.name(), child.isValid() ? "VALID" : "INVALID",
1149  child->IsVolumeMulti() ? "YES" : "NO" );
1150 
1151  } else if( cl == TGeoTrd1::Class()) {
1152  double dy = static_cast<const TGeoTrd1*>(shape)->GetDy();
1153  printout( ns.context()->debug_placements ? ALWAYS : DEBUG,
1154  "DD4CMS","+++ ...divide %s along %s (%d) with offset %6.3f cm and %6.3f cm to produce %d copies in %6.3f",
1155  parent.solid().type(), axis.c_str(), axesmap[axis], -dy + offset + width, width, nReplicas, dy );
1156  Volume child = parent.divide( childName, static_cast<int>( axesmap[axis]),
1157  nReplicas, -dy + offset + width, width );
1158 
1159  ns.context()->volumes[childName] = child;
1160 
1161  printout( ns.context()->debug_placements ? ALWAYS : DEBUG, "DD4CMS",
1162  "+++ %s Parent: %-24s [%s] Child: %-32s [%s] is multivolume [%s]",
1163  e.tag().c_str(),
1164  parentName.c_str(), parent.isValid() ? "VALID" : "INVALID",
1165  child.name(), child.isValid() ? "VALID" : "INVALID",
1166  child->IsVolumeMulti() ? "YES" : "NO" );
1167  }
1168  else {
1169  printout( ERROR, "DD4CMS", "++ FAILED Division of a %s is not implemented yet!", parent.solid().type());
1170  }
1171 }
1172 
1174 template <> void Converter<DDLAlgorithm>::operator()( xml_h element ) const {
1175  cms::DDNamespace ns( _param<cms::DDParsingContext>());
1176  xml_dim_t e( element );
1177  string name = e.nameStr();
1178  if( ns.context()->disabledAlgs.find( name ) != ns.context()->disabledAlgs.end()) {
1179  printout( INFO, "DD4CMS", "+++ Skip disabled algorithms: %s", name.c_str());
1180  return;
1181  }
1182  try {
1183  size_t idx;
1185  string type = "DDCMS_" + ns.realName( name );
1186  while(( idx = type.find( NAMESPACE_SEP )) != string::npos ) type[idx] = '_';
1187 
1188  // SensitiveDetector and Segmentation currently are undefined. Let's keep it like this
1189  // until we found something better.....
1190  printout( ns.context()->debug_algorithms ? ALWAYS : DEBUG,
1191  "DD4CMS","+++ Start executing algorithm %s....", type.c_str());
1192 
1193  long ret = PluginService::Create<long>( type, &description, ns.context(), &element, &sd );
1194  if( ret == 1 ) {
1195  printout( ns.context()->debug_algorithms ? ALWAYS : DEBUG,
1196  "DD4CMS", "+++ Executed algorithm: %08lX = %s", ret, name.c_str());
1197  return;
1198  }
1199 #if 0
1200  Segmentation seg;
1201  DetElement det(PluginService::Create<NamedObject*>(type, &description, ns.context(), &element, &sd));
1202  if(det.isValid()) {
1203  // setChildTitles(make_pair(name, det));
1204  if( sd.isValid() ) {
1205  det->flag |= DetElement::Object::HAVE_SENSITIVE_DETECTOR;
1206  }
1207  if( seg.isValid() ) {
1208  seg->sensitive = sd;
1209  seg->detector = det;
1210  }
1211  }
1212  if(!det.isValid()) {
1213  PluginDebug dbg;
1214  PluginService::Create<NamedObject*>(type, &description, ns.context, &element, &sd);
1215  except("DD4CMS","Failed to execute subdetector creation plugin. " + dbg.missingFactory(type));
1216  }
1217  description.addDetector(det);
1218 #endif
1219  printout(ERROR, "DD4CMS", "++ FAILED NOT ADDING SUBDETECTOR %08lX = %s",ret, name.c_str());
1221  return;
1222  }
1223  catch (const exception& exc) {
1224  printout(ERROR, "DD4CMS", "++ FAILED to convert subdetector: %s: %s", name.c_str(), exc.what());
1225  terminate();
1226  }
1227  catch (...) {
1228  printout(ERROR, "DD4CMS", "++ FAILED to convert subdetector: %s: %s", name.c_str(), "UNKNONW Exception");
1229  terminate();
1230  }
1231 }
1232 
1233 template <class InputIt, class ForwardIt, class BinOp>
1234 void for_each_token( InputIt first, InputIt last,
1235  ForwardIt s_first, ForwardIt s_last,
1236  BinOp binary_op)
1237 {
1238  while( first != last ) {
1239  const auto pos = std::find_first_of( first, last, s_first, s_last );
1240  binary_op( first, pos );
1241  if( pos == last ) break;
1242  first = std::next( pos );
1243  }
1244 }
1245 
1246 vector<double>
1247 splitNumeric( const string& str, const string& delims = "," )
1248 {
1249  vector<double> output;
1250 
1251  for_each_token( cbegin( str ), cend( str ),
1252  cbegin( delims ), cend( delims ),
1253  [&output] ( auto first, auto second ) {
1254  if( first != second ) {
1255  output.emplace_back(stod(string( first, second )));
1256  }
1257  });
1258  return output;
1259 }
1260 
1261 vector<string>
1262 splitString( const string& str, const string& delims = "," )
1263 {
1264  vector<string> output;
1265 
1266  for_each_token( cbegin( str ), cend( str ),
1267  cbegin( delims ), cend( delims ),
1268  [&output] ( auto first, auto second ) {
1269  if( first != second ) {
1270  output.emplace_back( first, second );
1271  }
1272  });
1273  return output;
1274 }
1275 
1278 template <> void Converter<DDLVector>::operator()( xml_h element ) const {
1279  cms::DDNamespace ns( _param<cms::DDParsingContext>());
1280  cms::DDParsingContext* const context = ns.context();
1281  DDVectorsMap* registry = context->description->extension<DDVectorsMap>();
1282  xml_dim_t e( element );
1283  string name = e.nameStr();
1284  string type = ns.attr<string>( e, _U( type ));
1285  string nEntries = ns.attr<string>( e, DD_CMU( nEntries ));
1286  string val = e.text();
1287  val.erase( remove_if( val.begin(), val.end(), []( unsigned char x ){ return isspace( x ); }), val.end());
1288 
1289  printout( ns.context()->debug_constants ? ALWAYS : DEBUG,
1290  "DD4CMS","+++ Vector<%s>: %s[%s]: %s", type.c_str(), name.c_str(),
1291  nEntries.c_str(), val.c_str());
1292 
1293  vector<double> results = splitNumeric( val );
1294  registry->insert( { name, results } );
1295 }
1296 
1297 template <> void Converter<debug>::operator()(xml_h dbg) const {
1298  cms::DDNamespace ns(_param<cms::DDParsingContext>());
1299  if( dbg.hasChild(DD_CMU(debug_visattr)) ) ns.setContext()->debug_visattr = true;
1300  if( dbg.hasChild(DD_CMU(debug_constants)) ) ns.setContext()->debug_constants = true;
1301  if( dbg.hasChild(DD_CMU(debug_materials)) ) ns.setContext()->debug_materials = true;
1302  if( dbg.hasChild(DD_CMU(debug_rotations)) ) ns.setContext()->debug_rotations = true;
1303  if( dbg.hasChild(DD_CMU(debug_shapes)) ) ns.setContext()->debug_shapes = true;
1304  if( dbg.hasChild(DD_CMU(debug_volumes)) ) ns.setContext()->debug_volumes = true;
1305  if( dbg.hasChild(DD_CMU(debug_placements)) ) ns.setContext()->debug_placements = true;
1306  if( dbg.hasChild(DD_CMU(debug_namespaces)) ) ns.setContext()->debug_namespaces = true;
1307  if( dbg.hasChild(DD_CMU(debug_includes)) ) ns.setContext()->debug_includes = true;
1308  if( dbg.hasChild(DD_CMU(debug_algorithms)) ) ns.setContext()->debug_algorithms = true;
1309  if( dbg.hasChild(DD_CMU(debug_specpars)) ) ns.setContext()->debug_specpars = true;
1310 }
1311 
1312 template <> void Converter<DDRegistry>::operator()(xml_h /* element */) const {
1313  cms::DDParsingContext* context = _param<cms::DDParsingContext>();
1314  DDRegistry* res = _option<DDRegistry>();
1315  cms::DDNamespace ns( context );
1316 
1317  printout( context->debug_constants ? ALWAYS : DEBUG,
1318  "DD4CMS","+++ RESOLVING %ld unknown constants.....", res->unresolvedConst.size());
1319 
1320  // FIXME: Avoid an infinite loop in a case
1321  // when a referred constant is not defined
1322  while( !res->unresolvedConst.empty()) {
1323  for( auto i : res->unresolvedConst ) {
1324  const string& n = i.first;
1325  string rep;
1326  string& v = i.second;
1327  size_t idx, idq;
1328  for( idx = v.find( '[', 0 ); idx != string::npos; idx = v.find( '[', idx + 1 )) {
1329  idq = v.find( ']', idx + 1 );
1330  rep = v.substr( idx + 1, idq - idx - 1 );
1331  auto r = res->allConst.find( rep );
1332  if( r != res->allConst.end()) {
1333  rep = "(" + (*r).second + ")";
1334  v.replace( idx, idq - idx + 1, rep );
1335  }
1336  }
1337  if( v.find(']') == string::npos ) {
1338  if( v.find("-+") != string::npos || v.find("+-") != string::npos ) {
1339  while(( idx = v.find( "-+" )) != string::npos )
1340  v.replace( idx, 2, "-" );
1341  while(( idx = v.find( "+-" )) != string::npos )
1342  v.replace( idx, 2, "-" );
1343  }
1344  printout( context->debug_constants ? ALWAYS : DEBUG,
1345  "DD4CMS","+++ [%06ld] ---------- %-40s = %s",
1346  res->unresolvedConst.size() - 1, n.c_str(), res->originalConst[n].c_str());
1347  ns.addConstantNS( n, v, "number" );
1348  res->unresolvedConst.erase(n);
1349  break;
1350  }
1351  }
1352  }
1353  if( !res->unresolvedConst.empty()) {
1354  for( const auto& e : res->unresolvedConst )
1355  printout( ERROR, "DD4CMS", "+++ Unresolved constant: %-40s = %s.", e.first.c_str(), e.second.c_str());
1356  except( "DD4CMS", "++ FAILED to resolve %ld constant entries:", res->unresolvedConst.size());
1357  }
1358  res->unresolvedConst.clear();
1359  res->originalConst.clear();
1360  res->allConst.clear();
1361 }
1362 
1363 template <> void Converter<print_xml_doc>::operator()(xml_h element) const {
1364  string fname = xml::DocumentHandler::system_path(element);
1365  printout(_param<cms::DDParsingContext>()->debug_includes ? ALWAYS : DEBUG,
1366  "DD4CMS","+++ Processing data from: %s",fname.c_str());
1367 }
1368 
1370 static long load_dddefinition(Detector& det, xml_h element) {
1371  static cms::DDParsingContext context(&det);
1372  cms::DDNamespace ns(context);
1373  ns.addConstantNS( "world_x", "5*m", "number" );
1374  ns.addConstantNS( "world_y", "5*m", "number" );
1375  ns.addConstantNS( "world_z", "5*m", "number" );
1376  ns.addConstantNS( "Air", "materials:Air", "string" );
1377  ns.addConstantNS( "Vacuum", "materials:Vacuum", "string" );
1378  ns.addConstantNS( "fm", "1e-12*m", "number" );
1379 
1380  xml_elt_t dddef(element);
1381  string fname = xml::DocumentHandler::system_path(element);
1382  bool open_geometry = dddef.hasChild(DD_CMU(open_geometry));
1383  bool close_geometry = dddef.hasChild(DD_CMU(close_geometry));
1384 
1385  xml_coll_t(dddef, _U(debug)).for_each(Converter<debug>(det,&context));
1386 
1387  // Here we define the order how XML elements are processed.
1388  // Be aware of dependencies. This can only defined once.
1389  // At the end it is a limitation of DOM....
1390  printout(INFO,"DD4CMS","+++ Processing the CMS detector description %s",fname.c_str());
1391 
1392  xml::Document doc;
1393  Converter<print_xml_doc> print_doc(det,&context);
1394  try {
1395  DDRegistry res;
1396  print_doc((doc=dddef.document()).root());
1397  xml_coll_t(dddef, DD_CMU(DisabledAlgo)).for_each(Converter<disabled_algo>(det,&context,&res));
1398  xml_coll_t(dddef, DD_CMU(ConstantsSection)).for_each(Converter<ConstantsSection>(det,&context,&res));
1399  xml_coll_t(dddef, DD_CMU(VisSection)).for_each(Converter<vissection>(det,&context));
1400  xml_coll_t(dddef, DD_CMU(RotationSection)).for_each(Converter<RotationSection>(det,&context));
1401  xml_coll_t(dddef, DD_CMU(MaterialSection)).for_each(Converter<MaterialSection>(det,&context));
1402 
1403  xml_coll_t(dddef, DD_CMU(IncludeSection)).for_each(DD_CMU(Include), Converter<include_load>(det,&context,&res));
1404 
1405  for(xml::Document d : res.includes ) {
1406  print_doc((doc=d).root());
1407  Converter<include_constants>(det,&context,&res)((doc=d).root());
1408  }
1409  // Before we continue, we have to resolve all constants NOW!
1410  Converter<DDRegistry>(det,&context,&res)(dddef);
1411  // Now we can process the include files one by one.....
1412  for(xml::Document d : res.includes ) {
1413  print_doc((doc=d).root());
1414  xml_coll_t(d.root(),DD_CMU(MaterialSection)).for_each(Converter<MaterialSection>(det,&context));
1415  }
1416  if( open_geometry ) {
1417  context.geo_inited = true;
1418  det.init();
1419  ns.addVolume(det.worldVolume());
1420  }
1421  for(xml::Document d : res.includes ) {
1422  print_doc((doc=d).root());
1423  xml_coll_t(d.root(),DD_CMU(RotationSection)).for_each(Converter<RotationSection>(det,&context));
1424  }
1425  for(xml::Document d : res.includes ) {
1426  print_doc((doc=d).root());
1427  xml_coll_t(d.root(), DD_CMU(SolidSection)).for_each(Converter<SolidSection>(det,&context));
1428  }
1429  for(xml::Document d : res.includes ) {
1430  print_doc((doc=d).root());
1431  xml_coll_t(d.root(), DD_CMU(LogicalPartSection)).for_each(Converter<LogicalPartSection>(det,&context));
1432  }
1433  for(xml::Document d : res.includes ) {
1434  print_doc((doc=d).root());
1435  xml_coll_t(d.root(), DD_CMU(Algorithm)).for_each(Converter<DDLAlgorithm>(det,&context));
1436  }
1437  for(xml::Document d : res.includes ) {
1438  print_doc((doc=d).root());
1439  xml_coll_t(d.root(), DD_CMU(PosPartSection)).for_each(Converter<PosPartSection>(det,&context));
1440  }
1441  for(xml::Document d : res.includes ) {
1442  print_doc((doc=d).root());
1443  xml_coll_t(d.root(), DD_CMU(SpecParSection)).for_each(Converter<SpecParSection>(det,&context));
1444  }
1445 
1447  for(xml::Document d : res.includes ) Converter<include_unload>(det,&context,&res)(d.root());
1448 
1449  print_doc((doc=dddef.document()).root());
1450  // Now process the actual geometry items
1451  xml_coll_t(dddef, DD_CMU(SolidSection)).for_each(Converter<SolidSection>(det,&context));
1452  xml_coll_t(dddef, DD_CMU(LogicalPartSection)).for_each(Converter<LogicalPartSection>(det,&context));
1453  xml_coll_t(dddef, DD_CMU(Algorithm)).for_each(Converter<DDLAlgorithm>(det,&context));
1454  xml_coll_t(dddef, DD_CMU(PosPartSection)).for_each(Converter<PosPartSection>(det,&context));
1455  xml_coll_t(dddef, DD_CMU(SpecParSection)).for_each(Converter<SpecParSection>(det,&context));
1456  }
1457  catch(const exception& e) {
1458  printout(ERROR,"DD4CMS","Exception while processing xml source:%s",doc.uri().c_str());
1459  printout(ERROR,"DD4CMS","----> %s", e.what());
1460  throw;
1461  }
1462 
1464  if( close_geometry ) {
1465  det.endDocument();
1466  }
1467  printout(INFO,"DDDefinition","+++ Finished processing %s",fname.c_str());
1468  return 1;
1469 }
1470 
1471 // Now declare the factory entry for the plugin mechanism
1472 DECLARE_XML_DOC_READER(DDDefinition,load_dddefinition)
DDLPosPart handles PosPart elements.
Definition: DDLPosPart.h:27
type
Definition: HCALResponse.h:21
#define DEBUG
dd4hep::Volume volume(const std::string &name, bool exc=true) const
Definition: DDNamespace.cc:189
float alpha
Definition: AMPTWrapper.h:95
DDLSphere processes all Sphere elements.
Definition: DDLSphere.h:24
DDLDivision processes Division elements.
Definition: DDLDivision.h:27
std::map< std::string, std::string > allConst
cms::DDDetector::DDVectorsMap DDVectorsMap
def copy(args, dbName)
std::set< std::string > disabledAlgs
ROOT::Math::Plane3D::Vector Vector
Definition: EcalHitMaker.cc:29
DDLVector handles Rotation and ReflectionRotation elements.
Definition: DDLVector.h:29
dd4hep::Detector * description
Geom::Theta< T > theta() const
static const int WARNING
DDLEllipticalTube processes all EllipticalTube elements.
dd4hep::Volume addVolume(dd4hep::Volume vol) const
Add rotation matrix to current namespace.
Definition: DDNamespace.cc:175
dd4hep::Solid solid(const std::string &name) const
Definition: DDNamespace.cc:227
DDLAlgorithm processes Algorithm elements.
Definition: DDLAlgorithm.h:25
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
Definition: Activities.doc:4
Definition: Electron.h:6
dd4hep::Rotation3D makeRotation3D(double thetaX, double phiX, double thetaY, double phiY, double thetaZ, double phiZ)
DDParsingContext *const context() const
Definition: DDNamespace.h:62
U second(std::pair< T, U > const &p)
void addConstantNS(const std::string &name, const std::string &value, const std::string &type) const
Definition: DDNamespace.cc:108
DDLBox processes Box elements.
Definition: DDLBox.h:27
DDLElementaryMaterial processes ElementaryMaterial elements.
vector< string > splitString(const string &str, const string &delims=",")
std::string realName(const std::string &) const
Definition: DDNamespace.cc:65
T attr(xml_elt_t element, const xml_tag_t &name) const
Definition: DDNamespace.h:32
DDLCone processes all Cone elements.
Definition: DDLCone.h:27
vector< double > splitNumeric(const string &str, const string &delims=",")
std::unordered_map< std::string, dd4hep::Volume > volumes
dd4hep::Rotation3D makeRotReflect(double thetaX, double phiX, double thetaY, double phiY, double thetaZ, double phiZ)
def pv(vc)
Definition: MetAnalyzer.py:7
double f[11][100]
constexpr unsigned int hash(const char *str, int h=0)
Definition: value.py:1
#define DD_CMU(a)
Definition: DDXMLTags.h:188
static void convert_boolean(cms::DDParsingContext *context, xml_h element)
rep
Definition: cuy.py:1190
#define M_PI
Namespace of DDCMS conversion namespace.
DDLTubs processes Tubs elements.
Definition: DDLTubs.h:21
Polynomial< 0 > Constant
Definition: Constant.h:6
def green(string)
std::map< std::string, std::string > originalConst
def ls(path, rec=False)
Definition: eostools.py:349
#define debug
Definition: HDRShower.cc:19
dd4hep::Solid addSolid(const std::string &name, dd4hep::Solid solid) const
Definition: DDNamespace.cc:221
DDLLogicalPart processes LogicalPart elements.
double sd
const std::string & name() const
Definition: DDNamespace.h:65
double b
Definition: hdecay.h:120
DDLRotationByAxis handles RotationByAxis elements.
std::unordered_map< std::string, std::vector< double >> DDVectorsMap
Definition: DDDetector.h:16
DDLCompositeMaterial processes all CompositeMaterial elements.
std::map< std::string, std::string > unresolvedConst
string fname
main script
#define ConvertTo(_x, _y)
Definition: DDUnits.h:6
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
Definition: DDAxes.h:11
static Interceptor::Registry registry("Interceptor")
#define str(s)
DDLRotationSequence handles a set of Rotations.
void for_each_token(InputIt first, InputIt last, ForwardIt s_first, ForwardIt s_last, BinOp binary_op)
static const int ERROR
#define NAMESPACE_SEP
Definition: DDNamespace.h:77
T angle(T x1, T y1, T z1, T x2, T y2, T z2)
Definition: angle.h:11
DDParsingContext * setContext()
Definition: DDNamespace.h:63