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