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