DD4hep  1.31.0
Detector Description Toolkit for High Energy Physics
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ShapePlugins.cpp
Go to the documentation of this file.
1 //==========================================================================
2 // AIDA Detector description implementation
3 //--------------------------------------------------------------------------
4 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5 // All rights reserved.
6 //
7 // For the licensing terms see $DD4hepINSTALL/LICENSE.
8 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9 //
10 // Author : M.Frank
11 //
12 //==========================================================================
13 
14 // Framework include files
16 #include <DD4hep/Printout.h>
17 #include <XML/Utilities.h>
18 #include <DD4hep/ShapeTags.h>
19 #include <TGeoScaledShape.h>
20 #include <TGeoShapeAssembly.h>
21 #include <TSystem.h>
22 #include <TClass.h>
23 
24 // C/C++ include files
25 #include <fstream>
26 
27 using namespace dd4hep;
28 using namespace dd4hep::detail;
29 
31 
44 static Handle<TObject> create_Scaled(Detector&, xml_h e) {
45  xml_dim_t scale(e);
46  Solid shape(xml_comp_t(scale.child(_U(shape))).createShape());
47  Solid solid = Scale(shape.ptr(), scale.x(1.0), scale.y(1.0), scale.z(1.0));
48  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
49  return solid;
50 }
51 DECLARE_XML_SHAPE(Scale__shape_constructor,create_Scaled)
52 
53 
65 static Handle<TObject> create_Assembly(Detector&, xml_h e) {
66  xml_dim_t dim(e);
67  Solid solid = Handle<TNamed>(new TGeoShapeAssembly());
68  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
69  return solid;
70 }
71 DECLARE_XML_SHAPE(Assembly__shape_constructor,create_Assembly)
72 
73 
85 static Handle<TObject> create_Box(Detector&, xml_h e) {
86  xml_dim_t dim(e);
87  Solid solid = Box(dim.dx(),dim.dy(),dim.dz());
88  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
89  return solid;
90 }
91 DECLARE_XML_SHAPE(Box__shape_constructor,create_Box)
92 
93 
107 static Handle<TObject> create_HalfSpace(Detector&, xml_h e) {
108  xml_dim_t dim(e);
109  xml_dim_t point = e.child(_U(point));
110  xml_dim_t normal = e.child(_U(normal));
111  double p[3] = { point.x(), point.y(), point.z()};
112  double n[3] = { normal.x(), normal.y(), normal.z()};
113  Solid solid = HalfSpace(p, n);
114  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
115  return solid;
116 }
117 DECLARE_XML_SHAPE(HalfSpace__shape_constructor,create_HalfSpace)
118 
119 
131 static Handle<TObject> create_Cone(Detector&, xml_h element) {
132  xml_dim_t e(element);
133  double rmi1 = e.rmin1(0.0), rma1 = e.rmax1();
134  Solid solid = Cone(e.z(0.0), rmi1, rma1, e.rmin2(rmi1), e.rmax2(rma1));
135  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
136  return solid;
137 }
138 DECLARE_XML_SHAPE(Cone__shape_constructor,create_Cone)
139 
140 
157 static Handle<TObject> create_Polycone(Detector&, xml_h element) {
158  xml_dim_t e(element);
159  int num = 0;
160  std::vector<double> rmin,rmax,z;
161  double start = e.startphi(0e0), deltaphi = e.deltaphi(2*M_PI);
162  for(xml_coll_t c(e,_U(zplane)); c; ++c, ++num) {
163  xml_comp_t plane(c);
164  rmin.emplace_back(plane.rmin(0.0));
165  rmax.emplace_back(plane.rmax());
166  z.emplace_back(plane.z());
167  }
168  if ( num < 2 ) {
169  throw std::runtime_error("PolyCone Shape> Not enough Z planes. minimum is 2!");
170  }
171  Solid solid = Polycone(start,deltaphi,rmin,rmax,z);
172  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
173  return solid;
174 }
175 DECLARE_XML_SHAPE(Polycone__shape_constructor,create_Polycone)
176 
177 
198 static Handle<TObject> create_ConeSegment(Detector&, xml_h element) {
199  Solid solid;
200  xml_dim_t e(element);
201  xml_attr_t aphi = element.attr_nothrow(_U(phi1));
202  xml_attr_t bphi = element.attr_nothrow(_U(phi2));
203  if ( aphi || bphi ) {
204  double phi1 = e.phi1(0.0);
205  double phi2 = e.phi2(2*M_PI);
207  solid = ConeSegment(e.dz(),e.rmin1(0.0),e.rmax1(),e.rmin2(0.0),e.rmax2(),phi1,phi2);
208  }
209  else {
210  double start_phi = e.startphi(0.0);
211  double delta_phi = e.deltaphi(2*M_PI);
212  while ( start_phi > 2.0*M_PI ) start_phi -= 2.0*M_PI;
214  solid = ConeSegment(e.dz(),e.rmin1(0.0),e.rmax1(),e.rmin2(0.0),e.rmax2(),start_phi,start_phi+delta_phi);
215  }
216  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
217  return solid;
218 }
219 DECLARE_XML_SHAPE(ConeSegment__shape_constructor,create_ConeSegment)
220 
221 
242 static Handle<TObject> create_Tube(Detector&, xml_h element) {
243  Solid solid;
244  xml_dim_t e(element);
245  xml_attr_t aphi = element.attr_nothrow(_U(phi1));
246  xml_attr_t bphi = element.attr_nothrow(_U(phi2));
247  if ( aphi || bphi ) {
248  double phi1 = e.phi1(0.0);
249  double phi2 = e.phi2(2*M_PI);
250  solid = Tube(e.rmin(0.0),e.rmax(),e.dz(0.0),phi1, phi2);
251  }
252  else {
253  double phi1 = e.startphi(0.0);
254  double phi2 = phi1 + e.deltaphi(2*M_PI);
255  solid = Tube(e.rmin(0.0),e.rmax(),e.dz(0.0),phi1,phi2);
256  }
257  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
258  return solid;
259 }
260 DECLARE_XML_SHAPE(Tube__shape_constructor,create_Tube)
261 
262 
268 static Handle<TObject> create_TwistedTube(Detector&, xml_h element) {
269  xml_dim_t e(element);
270  Solid solid;
271  int nseg = 1;
272  double zpos = 0.0, zneg = 0.0;
273  if ( element.attr_nothrow(_U(nsegments)) ) {
274  nseg = e.nsegments();
275  }
276  if ( element.attr_nothrow(_U(dz)) ) {
277  zneg = -1.0*(zpos = e.dz());
278  }
279  else {
280  zpos = e.zpos();
281  zneg = e.zneg();
282  }
283  solid = TwistedTube(e.twist(0.0), e.rmin(0.0),e.rmax(),zneg, zpos, nseg, e.deltaphi(2*M_PI));
284 
285  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
286  return solid;
287 }
288 DECLARE_XML_SHAPE(TwistedTube__shape_constructor,create_TwistedTube)
289 
290 
296 static Handle<TObject> create_CutTube(Detector&, xml_h element) {
297  xml_dim_t e(element);
298  Solid solid = CutTube(e.rmin(0.0),e.rmax(),e.dz(),
299  e.attr<double>(_U(phi1)),
300  e.attr<double>(_U(phi2)),
301  e.attr<double>(_U(lx)),
302  e.attr<double>(_U(ly)),
303  e.attr<double>(_U(lz)),
304  e.attr<double>(_U(tx)),
305  e.attr<double>(_U(ty)),
306  e.attr<double>(_U(tz)));
307  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
308  return solid;
309 }
310 DECLARE_XML_SHAPE(CutTube__shape_constructor,create_CutTube)
311 
312 
318 static Handle<TObject> create_EllipticalTube(Detector&, xml_h element) {
319  xml_dim_t e(element);
320  Solid solid = EllipticalTube(e.a(),e.b(),e.dz());
321  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
322  return solid;
323 }
324 DECLARE_XML_SHAPE(EllipticalTube__shape_constructor,create_EllipticalTube)
325 
326 
332 static Handle<TObject> create_TruncatedTube(Detector&, xml_h element) {
333  xml_dim_t e(element);
334  double sp = e.startphi(0.0), dp = e.deltaphi(2*M_PI);
335  Solid solid = TruncatedTube(e.dz(), e.rmin(0.0), e.rmax(), sp, dp,
336  e.attr<double>(xml_tag_t("cutAtStart")),
337  e.attr<double>(xml_tag_t("cutAtDelta")),
338  e.attr<bool>(xml_tag_t("cutInside")));
339  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
340  return solid;
341 }
342 DECLARE_XML_SHAPE(TruncatedTube__shape_constructor,create_TruncatedTube)
343 
344 
364 static Handle<TObject> create_Trap(Detector&, xml_h element) {
365  xml_dim_t e(element);
366  Solid solid;
367  if ( e.hasAttr(_U(dz)) ) {
368  solid = Trap(e.dz(),e.dy(),e.dx(),_toDouble(_Unicode(pLTX)));
369  }
370  else {
371  xml_attr_t attr = 0;
372  double x1 = e.x1();
373  double x2 = e.x2();
374  double x3 = (attr=element.attr_nothrow(_U(x3))) ? element.attr<double>(attr) : x1;
375  double x4 = (attr=element.attr_nothrow(_U(x4))) ? element.attr<double>(attr) : x2;
376  double y1 = e.y1();
377  double y2 = (attr=element.attr_nothrow(_U(y2))) ? element.attr<double>(attr) : y1;
378  solid = Trap(e.z(0.0),e.theta(0),e.phi(0),y1,x1,x2,e.alpha1(0),y2,x3,x4,e.alpha2(0));
379  }
380  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
381  return solid;
382 }
383 DECLARE_XML_SHAPE(Trap__shape_constructor,create_Trap)
384 
385 
391 static Handle<TObject> create_PseudoTrap(Detector&, xml_h element) {
392  xml_dim_t e(element);
393  Solid solid = PseudoTrap(e.x1(),e.x2(),e.y1(),e.y2(),e.z(),e.radius(),e.attr<bool>(xml_tag_t("minusZ")));
394  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
395  return solid;
396 }
397 DECLARE_XML_SHAPE(PseudoTrap__shape_constructor,create_PseudoTrap)
398 
399 
410 static Handle<TObject> create_Trd1(Detector&, xml_h element) {
411  xml_dim_t e(element);
412  Solid solid = Trd1(e.x1(),e.x2(),e.y(),e.z(0.0));
413  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
414  return solid;
415 }
416 DECLARE_XML_SHAPE(Trd1__shape_constructor,create_Trd1)
417 
418 
429 static Handle<TObject> create_Trd2(Detector&, xml_h element) {
430  xml_dim_t e(element);
431  Solid solid = Trd2(e.x1(),e.x2(),e.y1(),e.y2(),e.z(0.0));
432  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
433  return solid;
434 }
435 DECLARE_XML_SHAPE(Trapezoid__shape_constructor,create_Trd2)
436 DECLARE_XML_SHAPE(Trd2__shape_constructor,create_Trd2)
437 
438 
456 static Handle<TObject> create_Torus(Detector&, xml_h element) {
457  Solid solid;
458  xml_dim_t e(element);
459  xml_attr_t aphi = element.attr_nothrow(_U(phi1));
460  xml_attr_t bphi = element.attr_nothrow(_U(phi2));
461  if ( aphi || bphi ) {
462  double phi1 = e.phi1(0.0);
463  double phi2 = e.phi2(2*M_PI);
465  solid = Torus(e.r(), e.rmin(0.0), e.rmax(), phi1, phi2-phi1);
466  }
467  else {
468  double start_phi = e.startphi(0.0);
469  double delta_phi = e.deltaphi(2*M_PI);
470  while ( start_phi > 2.0*M_PI ) start_phi -= 2.0*M_PI;
472  solid = Torus(e.r(), e.rmin(0.0), e.rmax(), start_phi, delta_phi);
473  }
474  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
475  return solid;
476 }
477 DECLARE_XML_SHAPE(Torus__shape_constructor,create_Torus)
478 
479 
494 static Handle<TObject> create_Sphere(Detector&, xml_h element) {
495  xml_dim_t e(element);
496  double startphi = e.phi(0e0);
497  double endphi = startphi + 2.*M_PI;
498  double starttheta = e.theta(0e0);
499  double endtheta = starttheta + M_PI;
500 
501  if ( e.hasAttr(_U(startphi)) ) {
502  startphi = e.startphi();
503  endphi = startphi + 2.*M_PI;
504  }
505  if ( e.hasAttr(_U(endphi)) )
506  endphi = e.endphi();
507  else if ( e.hasAttr(_U(deltaphi)) )
508  endphi = startphi + e.deltaphi();
509 
510  if ( e.hasAttr(_U(starttheta)) ) {
511  starttheta = e.starttheta();
512  endtheta = starttheta + M_PI;
513  }
514  if ( e.hasAttr(_U(endtheta)) )
515  endtheta = e.endtheta();
516  else if ( e.hasAttr(_U(deltatheta)) )
517  endtheta = starttheta + e.deltatheta();
518 
519  Solid solid = Sphere(e.rmin(0e0), e.rmax(), starttheta, endtheta, startphi, endphi);
520  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
521  return solid;
522 }
523 DECLARE_XML_SHAPE(Sphere__shape_constructor,create_Sphere)
524 
525 
536 static Handle<TObject> create_Paraboloid(Detector&, xml_h element) {
537  xml_dim_t e(element);
538  Solid solid = Paraboloid(e.rmin(0.0),e.rmax(),e.dz());
539  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
540  return solid;
541 }
542 DECLARE_XML_SHAPE(Paraboloid__shape_constructor,create_Paraboloid)
543 
544 
557 static Handle<TObject> create_Hyperboloid(Detector&, xml_h element) {
558  xml_dim_t e(element);
559  Solid solid = Hyperboloid(e.rmin(), e.inner_stereo(), e.rmax(), e.outer_stereo(), e.dz());
560  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
561  return solid;
562 }
563 DECLARE_XML_SHAPE(Hyperboloid__shape_constructor,create_Hyperboloid)
564 
565 
577 static Handle<TObject> create_PolyhedraRegular(Detector&, xml_h element) {
578  xml_dim_t e(element);
579  Solid solid = PolyhedraRegular(e.numsides(),e.rmin(),e.rmax(),e.dz());
580  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
581  return solid;
582 }
583 DECLARE_XML_SHAPE(PolyhedraRegular__shape_constructor,create_PolyhedraRegular)
584 
585 
599 static Handle<TObject> create_Polyhedra(Detector&, xml_h element) {
600  xml_dim_t e(element);
601  std::vector<double> z, rmin, rmax;
602  for ( xml_coll_t c(e,_U(plane)); c; ++c ) {
603  xml_comp_t plane(c);
604  rmin.emplace_back(plane.rmin());
605  rmax.emplace_back(plane.rmax());
606  z.emplace_back(plane.z());
607  }
608  Solid solid = Polyhedra(e.numsides(),e.startphi(),e.deltaphi(),z,rmin,rmax);
609  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
610  return solid;
611 }
612 DECLARE_XML_SHAPE(Polyhedra__shape_constructor,create_Polyhedra)
613 
614 
620 static Handle<TObject> create_ExtrudedPolygon(Detector&, xml_h element) {
621  xml_dim_t e(element);
622  std::vector<double> pt_x, pt_y, sec_z, sec_x, sec_y, sec_scale;
623  for ( xml_coll_t sec(element, _U(section)); sec; ++sec ) {
624  xml_dim_t section(sec);
625  sec_z.emplace_back(section.attr<double>(_U(z)));
626  sec_x.emplace_back(section.attr<double>(_U(x)));
627  sec_y.emplace_back(section.attr<double>(_U(y)));
628  sec_scale.emplace_back(section.attr<double>(_U(scale),1.0));
629  }
630  for ( xml_coll_t pt(element, _U(point)); pt; ++pt ) {
631  xml_dim_t point(pt);
632  pt_x.emplace_back(point.attr<double>(_U(x)));
633  pt_y.emplace_back(point.attr<double>(_U(y)));
634  }
635  Solid solid = ExtrudedPolygon(pt_x, pt_y, sec_z, sec_x, sec_y, sec_scale);
636  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
637  return solid;
638 }
639 DECLARE_XML_SHAPE(ExtrudedPolygon__shape_constructor,create_ExtrudedPolygon)
640 
641 
647 static Handle<TObject> create_EightPointSolid(Detector&, xml_h element) {
648  xml_dim_t e(element);
649  double v[8][2];
650  int num = 0;
651  memset(&v[0][0],0,sizeof(v));
652  for(xml_coll_t c(e,_Unicode(vertex)); c && num<8; ++c, ++num) {
653  xml_comp_t vtx(c);
654  v[num][0] = vtx.x();
655  v[num][1] = vtx.y();
656  }
657  Solid solid = EightPointSolid(e.dz(),&v[0][0]);
658  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
659  return solid;
660 }
661 DECLARE_XML_SHAPE(EightPointSolid__shape_constructor,create_EightPointSolid)
662 
663 
669 static Handle<TObject> create_TessellatedSolid(Detector&, xml_h element) {
670  xml_dim_t e(element);
671  std::vector<TessellatedSolid::Vertex> vertices;
672  for ( xml_coll_t vtx(element, _U(vertex)); vtx; ++vtx ) {
673  xml_dim_t v(vtx);
674  vertices.emplace_back(v.x(), v.y(), v.z());
675  }
676  int num_facets = 0;
677  for ( xml_coll_t facet(element, _U(facet)); facet; ++facet ) ++num_facets;
678  TessellatedSolid solid = TessellatedSolid(num_facets);
679  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
680  for ( xml_coll_t facet(element, _U(facet)); facet; ++facet ) {
681  xml_dim_t f(facet);
682  size_t i0 = f.attr<size_t>(_U(v0));
683  size_t i1 = f.attr<size_t>(_U(v1));
684  size_t i2 = f.attr<size_t>(_U(v2));
685  if ( f.hasAttr(_U(v3)) ) {
686  size_t i3 = f.attr<size_t>(_U(v3));
687  solid.addFacet(vertices[i0], vertices[i1], vertices[i2], vertices[i3]);
688  }
689  else {
690  solid.addFacet(vertices[i0], vertices[i1], vertices[i2]);
691  }
692  }
693  return solid;
694 }
695 DECLARE_XML_SHAPE(TessellatedSolid__shape_constructor,create_TessellatedSolid)
696 
697 
705 static Handle<TObject> create_BooleanShape(Detector&, xml_h element) {
706 
707  xml_det_t e(element);
708 
709  // get the two shape elements
710  xml_coll_t c( e ,_U(shape)) ;
711  xml_comp_t x_shape1( c ) ;
712  ++c ;
713  xml_comp_t x_shape2( c ) ;
714 
715  // and create solids
716  Solid solid1( xml_comp_t( std::move(x_shape1) ).createShape()) ;
717  Solid solid2( xml_comp_t( std::move(x_shape2) ).createShape()) ;
718 
719 
720  std::string op = e.attr<std::string>(_U(operation)) ;
721  std::transform( op.begin(), op.end(), op.begin(), ::tolower);
722 
723  Solid resultSolid ;
724 
725  bool useRot(false), usePos(false), useTrans(false);
726  Position pos ;
727  RotationZYX rot ;
728 
729  if( e.hasChild( _U(transformation) ) ) {
730  useTrans = true ;
731  }
732  if( e.hasChild( _U(position) ) ) {
733  usePos = true ;
734  xml_comp_t x_pos = e.position();
735  pos = Position( x_pos.x(0.0),x_pos.y(0.0),x_pos.z(0.0) );
736  }
737  if( e.hasChild( _U(rotation) ) ) {
738  useRot = true ;
739  xml_comp_t x_rot = e.rotation();
740  rot = RotationZYX( x_rot.z(0.0),x_rot.y(0.0),x_rot.x(0.0) ) ;
741  }
742 
743  if( op == "subtraction" ) {
744  if ( useTrans ) {
745  Transform3D tr = xml::createTransformation(e.child(_U(transformation)));
746  resultSolid = SubtractionSolid(solid1, solid2, tr);
747  }
748  else if( useRot && usePos ) {
749  resultSolid = SubtractionSolid(solid1, solid2, Transform3D(rot, pos));
750  }
751  else if( useRot )
752  resultSolid = SubtractionSolid(solid1, solid2, rot);
753  else if( usePos)
754  resultSolid = SubtractionSolid(solid1, solid2, pos);
755  else
756  resultSolid = SubtractionSolid(solid1, solid2);
757  }
758  else if( op == "union" ) {
759  if ( useTrans ) {
760  Transform3D tr = xml::createTransformation(e.child(_U(transformation)));
761  resultSolid = UnionSolid(solid1, solid2, tr);
762  }
763  else if( useRot && usePos )
764  resultSolid = UnionSolid(solid1, solid2, Transform3D(rot, pos));
765  else if( useRot)
766  resultSolid = UnionSolid(solid1, solid2, rot);
767  else if( usePos)
768  resultSolid = UnionSolid(solid1, solid2, pos);
769  else
770  resultSolid = UnionSolid(solid1, solid2);
771  }
772  else if( op == "intersection" ) {
773  if ( useTrans ) {
774  Transform3D tr = xml::createTransformation(e.child(_U(transformation)));
775  resultSolid = IntersectionSolid(solid1, solid2, tr);
776  }
777  else if( useRot && usePos )
778  resultSolid = IntersectionSolid(solid1, solid2, Transform3D(rot, pos));
779  else if( useRot)
780  resultSolid = IntersectionSolid(solid1, solid2, rot);
781  else if( usePos)
782  resultSolid = IntersectionSolid(solid1, solid2, pos);
783  else
784  resultSolid = IntersectionSolid(solid1, solid2) ;
785 
786  } else {
787 
788  throw std::runtime_error(std::string(" create_BooleanShape - unknown operation given: ") + op +
789  std::string(" - needs to be one of 'subtraction','union' or 'intersection' ") ) ;
790  }
791  Solid solid = resultSolid ;
792  if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
793  return solid;
794 }
795 DECLARE_XML_SHAPE(BooleanShapeOld__shape_constructor,create_BooleanShape)
796 
797 
798 static Handle<TObject> create_BooleanMulti(Detector& description, xml_h element) {
799  xml_det_t e(element);
800  // get the two shape elements
801  Solid tmp, solid, result;
802  int flag = 0;
803  Transform3D position, rotation, trafo;
804 
805  xml_attr_t attr = 0;
806  std::string op = e.attr<std::string>(_U(operation)) ;
807  std::transform( op.begin(), op.end(), op.begin(), ::tolower);
808  //printout(ALWAYS,"","Boolean shape ---> %s",op.c_str());
809  for (xml_coll_t i(e ,_U(star)); i; ++i ) {
810  xml_comp_t x_elt = i;
811  std::string tag = x_elt.tag();
812  if ( tag == "shape" && !result.isValid() ) {
813  result = xml::createShape(description, x_elt.typeStr(), x_elt);
814  if ( (attr=i.attr_nothrow(_U(name))) ) result->SetName(i.attr<std::string>(attr).c_str());
815  flag = 1;
816  }
817  else if ( tag == "shape" && !solid.isValid() ) {
818  solid = xml::createShape(description, x_elt.typeStr(), x_elt);
819  if ( (attr=i.attr_nothrow(_U(name))) ) result->SetName(i.attr<std::string>(attr).c_str());
820  flag = 3;
821  }
822  else if ( result.isValid() && solid.isValid() ) {
823  if ( tag == "position" ) {
824  if ( flag == 4 ) trafo = position * trafo;
825  else if ( flag == 5 ) trafo = (position * rotation) * trafo;
826  Position pos(x_elt.x(0), x_elt.y(0), x_elt.z(0));
827  position = Transform3D(pos);
828  rotation = Transform3D();
829  flag = 4;
830  }
831  else if ( tag == "positionRZPhi" ) {
832  if ( flag == 4 ) trafo = position * trafo;
833  else if ( flag == 5 ) trafo = (position * rotation) * trafo;
834  ROOT::Math::RhoZPhiVector pos(x_elt.r(0), x_elt.z(0), x_elt.phi(0));
835  position = Transform3D(pos);
836  rotation = Transform3D();
837  flag = 4;
838  }
839  else if ( tag == "transformation" ) {
840  if ( flag == 4 ) trafo = position * trafo;
841  else if ( flag == 5 ) trafo = (position * rotation) * trafo;
843  trafo = tr * trafo;
844  position = rotation = Transform3D();
845  flag = 3;
846  }
847  else if ( tag == "rotation" ) {
848  rotation = Transform3D(RotationZYX(x_elt.z(0), x_elt.y(0), x_elt.x(0)));
849  flag = 5;
850  }
851  else if ( tag == "shape" ) {
852  //cout << solid.name() << " Flag:" << flag << endl;
853  if ( flag == 4 ) trafo = position * trafo;
854  else if ( flag == 5 ) trafo = (position * rotation) * trafo;
855  tmp = Solid();
856  if( op == "subtraction" )
857  tmp = SubtractionSolid(result, solid, trafo);
858  else if( op == "union" )
859  tmp = UnionSolid(result, solid, trafo);
860  else if( op == "intersection" )
861  tmp = IntersectionSolid(result, solid, trafo);
862  else { // Error!
863  throw std::runtime_error(" create_BooleanShape - unknown operation given: " + op +
864  " - needs to be one of 'subtraction','union' or 'intersection' ");
865  }
866  result = tmp;
867  trafo = position = rotation = Transform3D();
868  solid = xml::createShape(description, x_elt.typeStr(), x_elt);
869  if ( (attr=i.attr_nothrow(_U(name))) ) result->SetName(i.attr<std::string>(attr).c_str());
870  flag = 3;
871  }
872  }
873  }
874  if ( flag >= 3 ) {
875  //cout << solid.name() << " Flag:" << flag << endl;
876  if ( flag == 4 ) trafo = position * trafo;
877  else if ( flag == 5 ) trafo = (position * rotation) * trafo;
878  if( op == "subtraction" )
879  tmp = SubtractionSolid(result, solid, trafo);
880  else if( op == "union" )
881  tmp = UnionSolid(result, solid, trafo);
882  else if( op == "intersection" )
883  tmp = IntersectionSolid(result, solid, trafo);
884  else { // Error!
885  throw std::runtime_error(" create_BooleanShape - unknown operation given: " + op +
886  " - needs to be one of 'subtraction','union' or 'intersection' ");
887  }
888  result = tmp;
889  }
890  attr = element.attr_nothrow(_U(name));
891  if ( attr ) {
892  std::string nam = element.attr<std::string>(attr);
893  result->SetName(nam.c_str());
894  }
895  return result;
896 }
897 DECLARE_XML_SHAPE(BooleanShape__shape_constructor,create_BooleanMulti)
898 
899 
906 static Handle<TObject> create_std_volume(Detector& description, xml_h element) {
907  return xml::createStdVolume(description, element);
908 }
909 DECLARE_XML_VOLUME(DD4hep_StdVolume,create_std_volume)
910 
911 
918 static Handle<TObject> create_gen_volume(Detector& description, xml_h element) {
919  xml_dim_t elt = element;
920  std::string typ = elt.attr<std::string>(_U(type));
921  return xml::createVolume(description, typ, element);
922 }
923 DECLARE_XML_VOLUME(DD4hep_GenericVolume,create_gen_volume)
924 
925 TGeoCombiTrans* createPlacement(const Rotation3D& iRot, const Position& iTrans) {
926  double elements[9];
927  iRot.GetComponents(elements);
928  TGeoRotation r;
929  r.SetMatrix(elements);
930  TGeoTranslation t(iTrans.x(), iTrans.y(), iTrans.z());
931  return new TGeoCombiTrans(t, r);
932 }
933 
935 
940 static Ref_t create_shape(Detector& description, xml_h e, SensitiveDetector sens) {
941  xml_det_t x_det = e;
942  std::string name = x_det.nameStr();
943  xml_dim_t x_reflect = x_det.child(_U(reflect), false);
944  DetElement det (name,x_det.id());
945  Material mat = description.air();
946  Assembly assembly (name);
947  PlacedVolume pv;
948  int count = 0;
949 
950  printout(DEBUG,"TestShape","+++ Create shape: %s build type is: %s",
951  name.c_str(), buildTypeName(description.buildType()).c_str());
952  if ( x_det.hasChild(_U(material)) ) {
953  mat = description.material(x_det.child(_U(material)).attr<std::string>(_U(name)));
954  printout(INFO,"TestShape","+++ Volume material is %s", mat.name());
955  }
956  for ( xml_coll_t itm(e, _U(check)); itm; ++itm, ++count ) {
957  xml_dim_t x_check = itm;
958  xml_comp_t shape (x_check.child(_U(shape)));
959  xml_dim_t pos (x_check.child(_U(position), false));
960  xml_dim_t rot (x_check.child(_U(rotation), false));
961  bool reflect = x_check.hasChild(_U(reflect));
962  bool reflectZ = x_check.hasChild(_U(reflect_z));
963  bool reflectY = x_check.hasChild(_U(reflect_y));
964  bool reflectX = x_check.hasChild(_U(reflect_x));
965  std::string shape_type = shape.typeStr();
966  Volume volume;
967  Solid solid;
968 
969  if ( shape_type == "CAD_Assembly" || shape_type == "CAD_MultiVolume" ) {
970  volume = xml::createVolume(description, shape_type, shape);
971  solid = volume->GetShape();
972  }
973  else if ( shape_type == "StdVolume" ) {
974  volume = xml::createStdVolume(description, shape.child(_U(volume)));
975  solid = volume->GetShape();
976  }
977  else if ( shape_type == "GenVolume" ) {
978  volume = xml::createVolume(description, shape_type, shape.child(_U(volume)));
979  solid = volume->GetShape();
980  }
981  else {
982  solid = xml::createShape(description, shape_type, shape);
983  volume = Volume(name+_toString(count,"_vol_%d"),solid, mat);
984  }
985  if ( x_det.hasChild(_U(sensitive)) ) {
986  std::string sens_type = x_det.child(_U(sensitive)).attr<std::string>(_U(type));
987  volume.setSensitiveDetector(sens);
988  sens.setType(sens_type);
989  printout(INFO,"TestShape","+++ Sensitive type is %s", sens_type.c_str());
990  }
991  volume.setVisAttributes(description, x_check.visStr());
992  solid->SetName(shape_type.c_str());
993 
994  Transform3D tr;
995  if ( pos.ptr() && rot.ptr() ) {
996  Rotation3D rot3D(RotationZYX(rot.z(0),rot.y(0),rot.x(0)));
997  Position pos3D(pos.x(0),pos.y(0),pos.z(0));
998  tr = Transform3D(rot3D, pos3D);
999  }
1000  else if ( pos.ptr() ) {
1001  tr = Transform3D(Rotation3D(),Position(pos.x(0),pos.y(0),pos.z(0)));
1002  }
1003  else if ( rot.ptr() ) {
1004  Rotation3D rot3D(RotationZYX(rot.z(0),rot.y(0),rot.x(0)));
1005  tr = Transform3D(rot3D,Position());
1006  }
1007 
1008  if ( reflect ) {
1009  tr = tr * Rotation3D(1., 0., 0., 0., 1., 0., 0., 0., -1.);
1010  }
1011  if ( reflectX ) {
1012  tr = tr * Rotation3D(-1.,0.,0.,0.,1.,0.,0.,0.,1.);
1013  }
1014  if ( reflectY ) {
1015  tr = tr * Rotation3D(1.,0.,0.,0.,-1.,0.,0.,0.,1.);
1016  }
1017  if ( reflectZ ) {
1018  tr = tr * Rotation3D(1.,0.,0.,0.,1.,0.,0.,0.,-1.);
1019  }
1020  pv = assembly.placeVolume(volume,tr);
1021 
1022  if ( x_check.hasAttr(_U(id)) ) {
1023  pv.addPhysVolID("check",x_check.id());
1024  printout(INFO,"TestShape","+++ Volume id is %d", x_check.id());
1025  }
1026  const char* nam = solid->GetName();
1027  printout(INFO,"TestShape","Created successfull shape of type: %s %c%s%c",
1028  shape_type.c_str(), nam ? '[' : ' ', nam ? nam : "" ,nam ? ']' : ' ');
1029 
1030  bool instance_test = false;
1031  if ( shape_type == "CAD_Assembly" || shape_type == "CAD_MultiVolume" ) {
1032  solid->SetTitle(shape_type.c_str());
1033  instance_test = true;
1034  }
1035  else if ( 0 == strcasecmp(solid->GetTitle(),BOX_TAG) )
1036  instance_test = isInstance<Box>(solid);
1037  else if ( 0 == strcasecmp(solid->GetTitle(),TUBE_TAG) )
1038  instance_test = isInstance<Tube>(solid);
1039  else if ( 0 == strcasecmp(solid->GetTitle(),CUTTUBE_TAG) )
1040  instance_test = isInstance<CutTube>(solid);
1041  else if ( 0 == strcasecmp(solid->GetTitle(),CONE_TAG) )
1042  instance_test = isInstance<Cone>(solid);
1043  else if ( 0 == strcasecmp(solid->GetTitle(),TRD1_TAG) )
1044  instance_test = isInstance<Trd1>(solid);
1045  else if ( 0 == strcasecmp(solid->GetTitle(),TRD2_TAG) )
1046  instance_test = isInstance<Trd2>(solid);
1047  else if ( 0 == strcasecmp(solid->GetTitle(),TORUS_TAG) )
1048  instance_test = isInstance<Torus>(solid);
1049  else if ( 0 == strcasecmp(solid->GetTitle(),SPHERE_TAG) )
1050  instance_test = isInstance<Sphere>(solid);
1051  else if ( 0 == strcasecmp(solid->GetTitle(),HALFSPACE_TAG) )
1052  instance_test = isInstance<HalfSpace>(solid);
1053  else if ( 0 == strcasecmp(solid->GetTitle(),CONESEGMENT_TAG) )
1054  instance_test = isInstance<ConeSegment>(solid);
1055  else if ( 0 == strcasecmp(solid->GetTitle(),PARABOLOID_TAG) )
1056  instance_test = isInstance<Paraboloid>(solid);
1057  else if ( 0 == strcasecmp(solid->GetTitle(),HYPERBOLOID_TAG) )
1058  instance_test = isInstance<Hyperboloid>(solid);
1059  else if ( 0 == strcasecmp(solid->GetTitle(),"PolyhedraRegular") )
1060  instance_test = isInstance<PolyhedraRegular>(solid);
1061  else if ( 0 == strcasecmp(solid->GetTitle(),POLYHEDRA_TAG) )
1062  instance_test = isInstance<Polyhedra>(solid);
1063  else if ( 0 == strcasecmp(solid->GetTitle(),ELLIPTICALTUBE_TAG) )
1064  instance_test = isInstance<EllipticalTube>(solid);
1065  else if ( 0 == strcasecmp(solid->GetTitle(),EXTRUDEDPOLYGON_TAG) )
1066  instance_test = isInstance<ExtrudedPolygon>(solid);
1067  else if ( 0 == strcasecmp(solid->GetTitle(),SCALE_TAG) )
1068  instance_test = isInstance<Scale>(solid);
1069  else if ( 0 == strcasecmp(solid->GetTitle(),TESSELLATEDSOLID_TAG) ) {
1070  instance_test = isInstance<TessellatedSolid>(solid);
1071  shape_type = TESSELLATEDSOLID_TAG;
1072  }
1073  else if ( 0 == strcasecmp(solid->GetTitle(),POLYCONE_TAG) )
1074  instance_test = isInstance<Polycone>(solid);
1075  else if ( 0 == strcasecmp(solid->GetTitle(),TWISTEDTUBE_TAG) ) {
1076  instance_test = isInstance<TwistedTube>(solid);
1077  instance_test &= isInstance<Tube>(solid);
1078  instance_test &= isA<TwistedTube>(solid);
1079  instance_test &= !isA<Tube>(solid);
1080  }
1081  else if ( 0 == strcasecmp(solid->GetTitle(),EIGHTPOINTSOLID_TAG) ) {
1082  instance_test = isInstance<EightPointSolid>(solid);
1083  instance_test &= !isInstance<Trap>(solid);
1084  instance_test &= isA<EightPointSolid>(solid);
1085  instance_test &= !isA<Trap>(solid);
1086  }
1087  else if ( 0 == strcasecmp(solid->GetTitle(),TRAP_TAG) ) {
1088  instance_test = isInstance<EightPointSolid>(solid);
1089  instance_test &= isInstance<Trap>(solid);
1090  instance_test &= isA<Trap>(solid);
1091  instance_test &= !isA<EightPointSolid>(solid);
1092  }
1093  else if ( 0 == strcasecmp(solid->GetTitle(),SUBTRACTION_TAG) ) {
1094  instance_test = isInstance<BooleanSolid>(solid);
1095  instance_test &= isInstance<SubtractionSolid>(solid);
1096  instance_test &= !isA<IntersectionSolid>(solid);
1097  instance_test &= !isA<UnionSolid>(solid);
1098  instance_test &= isA<SubtractionSolid>(solid);
1099  instance_test &= !isA<PseudoTrap>(solid);
1100  }
1101  else if ( 0 == strcasecmp(solid->GetTitle(),UNION_TAG) ) {
1102  instance_test = isInstance<BooleanSolid>(solid);
1103  instance_test &= isInstance<UnionSolid>(solid);
1104  instance_test &= !isA<IntersectionSolid>(solid);
1105  instance_test &= isA<UnionSolid>(solid);
1106  instance_test &= !isA<SubtractionSolid>(solid);
1107  instance_test &= !isA<PseudoTrap>(solid);
1108  }
1109  else if ( 0 == strcasecmp(solid->GetTitle(),INTERSECTION_TAG) ) {
1110  instance_test = isInstance<BooleanSolid>(solid);
1111  instance_test &= isInstance<IntersectionSolid>(solid);
1112  instance_test &= isA<IntersectionSolid>(solid);
1113  instance_test &= !isA<UnionSolid>(solid);
1114  instance_test &= !isA<SubtractionSolid>(solid);
1115  instance_test &= !isA<PseudoTrap>(solid);
1116  }
1117  else if ( 0 == strcasecmp(solid->GetTitle(),TRUNCATEDTUBE_TAG) ) {
1118  instance_test = isInstance<BooleanSolid>(solid);
1119  instance_test &= isInstance<TruncatedTube>(solid);
1120  instance_test &= isA<TruncatedTube>(solid);
1121  instance_test &= !isA<PseudoTrap>(solid);
1122  instance_test &= !isA<IntersectionSolid>(solid);
1123  instance_test &= !isA<UnionSolid>(solid);
1124  instance_test &= !isA<SubtractionSolid>(solid);
1125  }
1126  else if ( 0 == strcasecmp(solid->GetTitle(),PSEUDOTRAP_TAG) ) {
1127  instance_test = isInstance<BooleanSolid>(solid);
1128  instance_test &= isInstance<PseudoTrap>(solid);
1129  instance_test &= isA<PseudoTrap>(solid);
1130  instance_test &= !isA<TruncatedTube>(solid);
1131  instance_test &= !isA<IntersectionSolid>(solid);
1132  instance_test &= !isA<UnionSolid>(solid);
1133  instance_test &= !isA<SubtractionSolid>(solid);
1134  }
1135 
1136  if ( !instance_test || ::strcasecmp(shape_type.c_str(),solid->GetTitle()) != 0 ) {
1137  printout(ERROR,"TestShape","BAD shape type: %s <-> %s Instance test: %s",
1138  shape_type.c_str(), solid->GetTitle(),
1139  instance_test ? "OK" : "FAILED");
1140  }
1141  else {
1142  printout(INFO,"TestShape","Correct shape type: %s %s <-> %s Instance test: %s",
1143  solid->GetName(), shape_type.c_str(), solid->GetTitle(), "OK");
1144  }
1145  }
1146  if ( x_reflect ) {
1147  xml_dim_t x_pos(x_reflect.child(_U(position), false));
1148  xml_dim_t x_rot(x_reflect.child(_U(rotation), false));
1149  DetElement full_detector(name+"_full",100+x_det.id());
1150  Assembly full_assembly(name+"_full");
1151  RotationZYX refl_rot;
1152  Position refl_pos;
1153 
1154  if ( x_rot ) refl_rot = RotationZYX(x_rot.z(0),x_rot.y(0),x_rot.x(0));
1155  if ( x_pos ) refl_pos = Position(x_pos.x(0),x_pos.y(0),x_pos.z(0));
1156  Transform3D refl_trafo(Rotation3D(refl_rot),refl_pos);
1157 
1159  pv = full_assembly.placeVolume(assembly);
1160  full_detector.add(det);
1161  det.setPlacement(pv);
1162 
1164  auto reflected = det.reflect(name+"_reflected",100+x_det.id());
1165  pv = full_assembly.placeVolume(reflected.second, refl_trafo);
1166  full_detector.add(reflected.first);
1167  reflected.first.setPlacement(pv);
1168 
1170  pv = description.worldVolume().placeVolume(full_assembly);
1171  full_detector.setPlacement(pv);
1172 
1173  det = full_detector;
1174  }
1175  else {
1176  pv = description.worldVolume().placeVolume(assembly);
1177  pv.addPhysVolID("system", x_det.id());
1178  det.setPlacement(pv);
1179  }
1181  for ( xml_coll_t itm(e, xml_tag_t("test")); itm; ++itm, ++count ) {
1182  xml_comp_t x_test = itm;
1183  std::string typ = x_test.typeStr();
1184  const void* argv[] = { &e, &pv, 0};
1185  Ref_t result = (NamedObject*)PluginService::Create<void*>(typ, &description, 2, (char**)argv);
1186  if ( !result.isValid() ) {
1187  printout(INFO,"TestShape","+++ Shape verification FAILED. [Plugin not found]");
1188  except("TestShape","+++ Shape verification FAILED.");
1189  }
1190  else if ( ::strcmp(result->GetName(),"SUCCESS") == 0 ) {
1191  printout(INFO,"TestShape","+++ Shape verification SUCCESSFUL. [type=%s]",name.c_str());
1192  delete result.ptr();
1193  }
1194  else {
1195  printout(INFO,"TestShape","+++ Shape verification FAILED [result=%s]",result->GetName());
1196  printout(INFO,"TestShape","+++ Diagnosis: \n%s",result->GetTitle());
1197  delete result.ptr();
1198  except("TestShape","+++ Shape verification FAILED.");
1199  }
1200  }
1201  return det;
1202 }
1203 
1204 // first argument is the type from the xml file
1205 DECLARE_DETELEMENT(DD4hep_TestShape_Creator,create_shape)
1206 
1207 
1213 void* shape_mesh_verifier(Detector& description, int argc, char** argv) {
1214  if ( argc != 2 ) { }
1215  xml_det_t x_det = *(xml_h*)argv[0];
1216  PlacedVolume pv = *(PlacedVolume*)argv[1];
1217  xml_comp_t x_test = x_det.child(xml_tag_t("test"));
1218  int ref_cr = x_test.hasAttr(_U(create)) ? x_test.attr<int>(_U(create)) : 0;
1219  int nseg = x_test.hasAttr(_U(segmentation)) ? x_test.attr<int>(_U(segmentation)) : -1;
1220  TString ref = x_test.refStr().c_str();
1221  std::string ref_str;
1222  std::stringstream os;
1223 
1224  if ( nseg > 0 ) {
1225  description.manager().SetNsegments(nseg);
1226  }
1227  Volume v = pv.volume();
1228  for (Int_t ipv=0, npv=v->GetNdaughters(); ipv < npv; ipv++) {
1229  PlacedVolume place = v->GetNode(ipv);
1230  auto vol = place.volume();
1231  auto solid = vol.solid();
1232  os << "ShapeCheck[" << ipv << "] ";
1233  os << toStringMesh(place, 2);
1234  printout(INFO,"Mesh_Verifier","+++ Checking mesh of %s %s [%s] vol:%s.",
1235  solid->IsA()->GetName(),
1236  solid->GetName(), solid->GetTitle(),
1237  vol->GetName());
1238  }
1239  gSystem->ExpandPathName(ref);
1240  if ( ref_cr ) {
1241  std::ofstream out(ref, std::fstream::out);
1242  if ( !out.is_open() ) {
1243  except("Mesh_Verifier","+++ FAILED to open(WRITE) reference file: "+x_test.refStr());
1244  }
1245  out << os.str();
1246  out.close();
1247  printout(INFO,"Mesh_Verifier","+++ Successfully wrote reference file: "+x_test.refStr());
1248  }
1249  else if ( ref.Length() > 0 ) {
1250  char c;
1251  std::ifstream in(ref.Data(), std::fstream::in);
1252  if ( !in.is_open() ) {
1253  except("Mesh_Verifier","+++ FAILED to access reference file: "+x_test.refStr());
1254  }
1255  while (in.get(c)) // loop getting single characters
1256  ref_str += c;
1257  in.close();
1258  printout(INFO,"Mesh_Verifier","+++ Successfully read reference file: "+x_test.refStr());
1259  if ( ref_str != os.str() ) {
1260  printout(ERROR,"Mesh_Verifier","+++ Output and reference differ! Please check.");
1261  return Constant("FAILURE",os.str().c_str()).ptr();
1262  }
1263  printout(INFO,"Mesh_Verifier","+++ Successfully checked CREATED shapes.");
1264  os.str("");
1265  for (Int_t ipv=0, npv=v->GetNdaughters(); ipv < npv; ipv++) {
1266  PlacedVolume place = v->GetNode(ipv);
1267  Solid solid = place.volume().solid();
1268  if ( isInstance<TruncatedTube>(solid) ) {
1269  auto params = solid.dimensions();
1270  solid.setDimensions(params);
1271  }
1272  else if ( isInstance<PseudoTrap>(solid) ) {
1273  auto params = solid.dimensions();
1274  solid.setDimensions(params);
1275  }
1276  else if ( solid->IsA() != TGeoCompositeShape::Class() ) {
1277  auto params = solid.dimensions();
1278  solid.setDimensions(params);
1279  }
1280  else {
1281  printout(INFO,"Mesh_Verifier","+++ Skip re-dimensioning of %s [%s].",
1282  solid->IsA()->GetName(), solid->GetTitle());
1283  }
1284  }
1285  for (Int_t ipv=0, npv=v->GetNdaughters(); ipv < npv; ipv++) {
1286  PlacedVolume place = v->GetNode(ipv);
1287  os << "ShapeCheck[" << ipv << "] ";
1288  os << toStringMesh(place, 2);
1289  }
1290  if ( ref_str != os.str() ) {
1291  printout(DEBUG,"Mesh_Verifier","+++ REFERENCE shape mesh:\n%s",ref_str.c_str());
1292  printout(DEBUG,"Mesh_Verifier","+++ REDIMENSIONED shape mesh:\n%s",os.str().c_str());
1293  printout(ERROR,"Mesh_Verifier","+++ Output and reference differ after re-dimension! Please check.");
1294  return Constant("FAILURE",os.str().c_str()).ptr();
1295  }
1296  printout(INFO,"Mesh_Verifier","+++ Successfully checked REDIMENSIONED shapes.");
1297  }
1298  return Constant("SUCCESS",os.str().c_str()).ptr();
1299 }
1300 DECLARE_DD4HEP_CONSTRUCTOR(DD4hep_Mesh_Verifier,shape_mesh_verifier)
dd4hep::isInstance< TwistedTube >
bool isInstance< TwistedTube >(const Handle< TGeoShape > &solid)
Definition: ShapeUtilities.cpp:100
dd4hep::isInstance< Torus >
template bool isInstance< Torus >(const Handle< TGeoShape > &solid)
dd4hep::xml::Collection_t
Class to support the access to collections of XmlNodes (or XmlElements)
Definition: XMLElements.h:636
dd4hep::isA< TruncatedTube >
bool isA< TruncatedTube >(const Handle< TGeoShape > &solid)
Definition: ShapeUtilities.cpp:157
dd4hep::isA< EightPointSolid >
template bool isA< EightPointSolid >(const Handle< TGeoShape > &solid)
dd4hep::TruncatedTube
Class describing a truncated tube shape (CMS'ism)
Definition: Shapes.h:780
dd4hep::isInstance< Tube >
bool isInstance< Tube >(const Handle< TGeoShape > &solid)
Definition: ShapeUtilities.cpp:85
TRD2_TAG
#define TRD2_TAG
Definition: ShapeTags.h:25
dd4hep::PolyhedraRegular
Class describing a regular polyhedron shape.
Definition: Shapes.h:1494
v
View * v
Definition: MultiView.cpp:28
dd4hep::PseudoTrap
Class describing a pseudo trap shape (CMS'ism)
Definition: Shapes.h:1061
dd4hep::SensitiveDetector
Handle class to hold the information of a sensitive detector.
Definition: DetElement.h:43
dd4hep::Torus
Class describing a Torus shape.
Definition: Shapes.h:1227
dd4hep::isInstance< TessellatedSolid >
template bool isInstance< TessellatedSolid >(const Handle< TGeoShape > &solid)
dd4hep::HalfSpace
Class describing half-space.
Definition: Shapes.h:352
DECLARE_DETELEMENT
#define DECLARE_DETELEMENT(name, func)
Definition: Factories.h:339
M_PI
#define M_PI
Definition: Handle.h:31
POLYCONE_TAG
#define POLYCONE_TAG
Definition: ShapeTags.h:19
TESSELLATEDSOLID_TAG
#define TESSELLATEDSOLID_TAG
Definition: ShapeTags.h:37
createPlacement
TGeoCombiTrans * createPlacement(const Rotation3D &iRot, const Position &iTrans)
Definition: ShapePlugins.cpp:925
HALFSPACE_TAG
#define HALFSPACE_TAG
Definition: ShapeTags.h:18
dd4hep::PlacedVolume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:164
dd4hep::isInstance< ExtrudedPolygon >
template bool isInstance< ExtrudedPolygon >(const Handle< TGeoShape > &solid)
ShapeTags.h
dd4hep::EllipticalTube
Class describing a twisted tube shape.
Definition: Shapes.h:842
dd4hep::NamedObject::GetName
const char * GetName() const
Access name.
Definition: NamedObject.h:58
dd4hep::PlacedVolume::addPhysVolID
PlacedVolume & addPhysVolID(const std::string &name, int value)
Add identifier.
Definition: Volumes.cpp:501
SPHERE_TAG
#define SPHERE_TAG
Definition: ShapeTags.h:30
dd4hep::Hyperboloid
Class describing a Hyperboloid shape.
Definition: Shapes.h:1435
dd4hep::Volume::solid
Solid solid() const
Access to Solid (Shape)
Definition: Volumes.cpp:1252
DECLARE_XML_SHAPE
#define DECLARE_XML_SHAPE(name, func)
Definition: Factories.h:306
dd4hep::Handle::isValid
bool isValid() const
Check the validity of the object held by the handle.
Definition: Handle.h:126
dd4hep::Handle
Handle: a templated class like a shared pointer, which allows specialized access to tgeometry objects...
Definition: Handle.h:82
dd4hep::_toString
std::string _toString(bool value)
String conversions: boolean value to string.
Definition: Handle.cpp:332
dd4hep::Rotation3D
ROOT::Math::Rotation3D Rotation3D
Definition: Objects.h:112
dd4hep::Trap
Class describing a trap shape.
Definition: Shapes.h:975
dd4hep::isInstance< BooleanSolid >
template bool isInstance< BooleanSolid >(const Handle< TGeoShape > &solid)
dd4hep::Solid_type< TGeoShape >
DECLARE_XML_VOLUME
#define DECLARE_XML_VOLUME(name, func)
Definition: Factories.h:311
dd4hep::isInstance< Polyhedra >
template bool isInstance< Polyhedra >(const Handle< TGeoShape > &solid)
dd4hep::xml::Handle_t
Class to easily access the properties of single XmlElements.
Definition: XMLElements.h:380
SCALE_TAG
#define SCALE_TAG
Definition: ShapeTags.h:33
dd4hep::Detector::worldVolume
virtual Volume worldVolume() const =0
Return handle to the world volume containing everything.
TRD1_TAG
#define TRD1_TAG
Definition: ShapeTags.h:24
dd4hep::isInstance< EllipticalTube >
template bool isInstance< EllipticalTube >(const Handle< TGeoShape > &solid)
dd4hep::Handle::name
const char * name() const
Access the object name (or "" if not supported by the object)
TUBE_TAG
#define TUBE_TAG
Definition: ShapeTags.h:21
UNION_TAG
#define UNION_TAG
Definition: ShapeTags.h:41
dd4hep::Assembly
Implementation class extending the ROOT assembly volumes (TGeoVolumeAssembly)
Definition: Volumes.h:762
dd4hep::isInstance< CutTube >
template bool isInstance< CutTube >(const Handle< TGeoShape > &solid)
dd4hep::Volume::placeVolume
PlacedVolume placeVolume(const Volume &volume) const
Place daughter volume. The position and rotation are the identity.
Definition: Volumes.cpp:859
dd4hep::isInstance< Hyperboloid >
template bool isInstance< Hyperboloid >(const Handle< TGeoShape > &solid)
dd4hep::Polyhedra
Class describing a regular polyhedron shape.
Definition: Shapes.h:1583
dd4hep::isInstance< Cone >
bool isInstance< Cone >(const Handle< TGeoShape > &solid)
Definition: ShapeUtilities.cpp:82
dd4hep::isInstance< SubtractionSolid >
bool isInstance< SubtractionSolid >(const Handle< TGeoShape > &solid)
Definition: ShapeUtilities.cpp:111
TRAP_TAG
#define TRAP_TAG
Definition: ShapeTags.h:32
dd4hep::IntersectionSolid
Class describing boolean intersection solid.
Definition: Shapes.h:1975
dd4hep::isInstance< TruncatedTube >
bool isInstance< TruncatedTube >(const Handle< TGeoShape > &solid)
Definition: ShapeUtilities.cpp:103
dd4hep::ConeSegment
Class describing a cone segment shape.
Definition: Shapes.h:543
xml_attr_t
dd4hep::xml::Attribute xml_attr_t
Definition: XML.h:27
xml_comp_t
dd4hep::xml::Component xml_comp_t
Definition: XML.h:33
_Unicode
#define _Unicode(a)
Definition: Tags.h:24
dd4hep::isInstance< ConeSegment >
template bool isInstance< ConeSegment >(const Handle< TGeoShape > &solid)
dd4hep::Trd2
Class describing a Trd2 shape.
Definition: Shapes.h:1164
dd4hep::Material
Handle class describing a material.
Definition: Objects.h:271
dd4hep::isInstance< Box >
template bool isInstance< Box >(const Handle< TGeoShape > &solid)
dd4hep::TessellatedSolid::addFacet
bool addFacet(const Vertex &pt0, const Vertex &pt1, const Vertex &pt2) const
Add new facet to the shape.
Definition: Shapes.cpp:811
dd4hep::xml::Tag_t
Class to support both way translation between C++ and XML strings.
Definition: XMLElements.h:254
dd4hep::xml::Handle_t::hasChild
bool hasChild(const XmlChar *tag) const
Check the existence of a child with a given tag name.
Definition: XMLElements.cpp:767
dd4hep::Detector::material
virtual Material material(const std::string &name) const =0
Retrieve a matrial by its name from the detector description.
dd4hep::DetElement
Handle class describing a detector element.
Definition: DetElement.h:187
dd4hep::isA< Tube >
template bool isA< Tube >(const Handle< TGeoShape > &solid)
dd4hep::Detector::air
virtual Material air() const =0
Return handle to material describing air.
dd4hep::Constant
Handle class describing a constant (define) object in description.
Definition: Objects.h:208
dd4hep::Volume
Handle class holding a placed volume (also called physical volume)
Definition: Volumes.h:371
dd4hep::Scale
Class describing a Scale shape.
Definition: Shapes.h:240
dd4hep::Volume::setSensitiveDetector
const Volume & setSensitiveDetector(const SensitiveDetector &obj) const
Assign the sensitive detector structure.
Definition: Volumes.cpp:1309
dd4hep::detail
DD4hep internal namespace.
Definition: Alignments.h:32
TWISTEDTUBE_TAG
#define TWISTEDTUBE_TAG
Definition: ShapeTags.h:29
dd4hep::xml::createShape
Solid createShape(Detector &description, const std::string &shape_type, xml::Element element)
Create a solid shape using the plugin mechanism from the attributes of the XML element.
Definition: Utilities.cpp:84
dd4hep::isInstance< Sphere >
template bool isInstance< Sphere >(const Handle< TGeoShape > &solid)
CONE_TAG
#define CONE_TAG
Definition: ShapeTags.h:20
PARABOLOID_TAG
#define PARABOLOID_TAG
Definition: ShapeTags.h:26
xml_det_t
dd4hep::xml::DetElement xml_det_t
Definition: XML.h:32
_U
#define _U(a)
Definition: Tags.h:23
TRUNCATEDTUBE_TAG
#define TRUNCATEDTUBE_TAG
Definition: ShapeTags.h:39
DECLARE_DD4HEP_CONSTRUCTOR
#define DECLARE_DD4HEP_CONSTRUCTOR(name, func)
Definition: Factories.h:291
dd4hep::isInstance< IntersectionSolid >
bool isInstance< IntersectionSolid >(const Handle< TGeoShape > &solid)
Definition: ShapeUtilities.cpp:121
dd4hep::Cone
Class describing a cone shape.
Definition: Shapes.h:403
dd4hep::isInstance< Polycone >
bool isInstance< Polycone >(const Handle< TGeoShape > &solid)
Definition: ShapeUtilities.cpp:90
SUBTRACTION_TAG
#define SUBTRACTION_TAG
Definition: ShapeTags.h:42
dd4hep::isInstance< EightPointSolid >
bool isInstance< EightPointSolid >(const Handle< TGeoShape > &solid)
Definition: ShapeUtilities.cpp:93
dd4hep::ExtrudedPolygon
Class describing a extruded polygon shape.
Definition: Shapes.h:1659
dd4hep::Trd1
Class describing a Trd1 shape.
Definition: Shapes.h:1104
CUTTUBE_TAG
#define CUTTUBE_TAG
Definition: ShapeTags.h:22
shape_mesh_verifier
void * shape_mesh_verifier(Detector &description, int argc, char **argv)
Plugin factory to check shape meshes against a reference file.
Definition: ShapePlugins.cpp:1213
dd4hep::isInstance< Trd2 >
template bool isInstance< Trd2 >(const Handle< TGeoShape > &solid)
EIGHTPOINTSOLID_TAG
#define EIGHTPOINTSOLID_TAG
Definition: ShapeTags.h:36
dd4hep::isInstance< UnionSolid >
bool isInstance< UnionSolid >(const Handle< TGeoShape > &solid)
Definition: ShapeUtilities.cpp:116
dd4hep::isInstance< Paraboloid >
template bool isInstance< Paraboloid >(const Handle< TGeoShape > &solid)
PSEUDOTRAP_TAG
#define PSEUDOTRAP_TAG
Definition: ShapeTags.h:40
dd4hep::xml::Handle_t::child
Handle_t child(const XmlChar *tag, bool throw_exception=true) const
Access a single child by its tag name (unicode)
Definition: XMLElements.cpp:713
dd4hep::UnionSolid
Class describing boolean union solid.
Definition: Shapes.h:1927
EXTRUDEDPOLYGON_TAG
#define EXTRUDEDPOLYGON_TAG
Definition: ShapeTags.h:35
dd4hep::NamedObject::GetTitle
const char * GetTitle() const
Get name (used by Handle)
Definition: NamedObject.h:70
dd4hep::CutTube
Class describing a tube shape of a section of a cut tube segment.
Definition: Shapes.h:717
dd4hep::Transform3D
ROOT::Math::Transform3D Transform3D
Definition: Objects.h:116
dd4hep::TwistedTube
Class describing a twisted tube shape.
Definition: Shapes.h:901
dd4hep::EightPointSolid
Class describing an arbitray solid defined by 8 vertices.
Definition: Shapes.h:1721
dd4hep::isInstance< HalfSpace >
template bool isInstance< HalfSpace >(const Handle< TGeoShape > &solid)
xml_tag_t
dd4hep::xml::Tag_t xml_tag_t
Definition: XML.h:26
dd4hep::Polycone
Class describing a Polycone shape.
Definition: Shapes.h:472
dd4hep::Position
ROOT::Math::XYZVector Position
Definition: Objects.h:80
CONESEGMENT_TAG
#define CONESEGMENT_TAG
Definition: ShapeTags.h:23
DetFactoryHelper.h
dd4hep::_toDouble
double _toDouble(const std::string &value)
String conversions: string to double value.
Definition: Handle.cpp:116
dd4hep::isInstance< Trd1 >
template bool isInstance< Trd1 >(const Handle< TGeoShape > &solid)
dd4hep::xml::createVolume
Volume createVolume(Detector &description, const std::string &type, xml::Element element)
Create a volume using the plugin mechanism from the attributes of the XML element.
Definition: Utilities.cpp:197
dd4hep::Detector::buildType
virtual DetectorBuildType buildType() const =0
Access flag to steer the detail of building of the geometry/detector description.
dd4hep::Box
Class describing a box shape.
Definition: Shapes.h:295
dd4hep::isA< IntersectionSolid >
bool isA< IntersectionSolid >(const Handle< TGeoShape > &solid)
Definition: ShapeUtilities.cpp:177
dd4hep::isA< SubtractionSolid >
bool isA< SubtractionSolid >(const Handle< TGeoShape > &solid)
Definition: ShapeUtilities.cpp:165
dd4hep::Handle::ptr
T * ptr() const
Access to the held object.
Definition: Handle.h:151
TORUS_TAG
#define TORUS_TAG
Definition: ShapeTags.h:31
dd4hep::Volume::setVisAttributes
const Volume & setVisAttributes(const VisAttr &obj) const
Set Visualization attributes to the volume.
Definition: Volumes.cpp:1156
dd4hep
Namespace for the AIDA detector description toolkit.
Definition: AlignmentsCalib.h:28
dd4hep::Sphere
Class describing a sphere shape.
Definition: Shapes.h:1289
dd4hep::NamedObject
Implementation of a named object.
Definition: NamedObject.h:30
dd4hep::buildTypeName
std::string buildTypeName(DetectorBuildType type)
Translate the geometry build type to value to the string representation.
Definition: BuildType.cpp:54
dd4hep::isA< Trap >
template bool isA< Trap >(const Handle< TGeoShape > &solid)
dd4hep::Solid
Solid_type< TGeoShape > Solid
Definition: Shapes.h:198
dd4hep::TessellatedSolid
Class describing a tessellated shape.
Definition: Shapes.h:1773
dd4hep::Solid_type::setDimensions
Solid_type & setDimensions(const std::vector< double > &params)
Set the shape dimensions. As for the TGeo shape, but angles in rad rather than degrees.
Definition: Shapes.cpp:95
det
DetElement::Object * det
Definition: AlignmentsCalculator.cpp:66
dd4hep::PlacedVolume::volume
Volume volume() const
Logical volume of this placement.
Definition: Volumes.cpp:468
dd4hep::isA< PseudoTrap >
bool isA< PseudoTrap >(const Handle< TGeoShape > &solid)
Definition: ShapeUtilities.cpp:161
BOX_TAG
#define BOX_TAG
Definition: ShapeTags.h:17
dd4hep::isA< TwistedTube >
bool isA< TwistedTube >(const Handle< TGeoShape > &solid)
Definition: ShapeUtilities.cpp:153
dd4hep::Detector
The main interface to the dd4hep detector description package.
Definition: Detector.h:90
dd4hep::sim::HepMC::vertex
Geant4Vertex * vertex(EventStream &info, int i)
Definition: Geant4EventReaderHepMC.cpp:363
dd4hep::isInstance< Scale >
template bool isInstance< Scale >(const Handle< TGeoShape > &solid)
INTERSECTION_TAG
#define INTERSECTION_TAG
Definition: ShapeTags.h:43
HYPERBOLOID_TAG
#define HYPERBOLOID_TAG
Definition: ShapeTags.h:27
dd4hep::xml::createTransformation
Transform3D createTransformation(xml::Element element)
Create layered transformation from xml information.
Definition: Utilities.cpp:42
dd4hep::RotationZYX
ROOT::Math::RotationZYX RotationZYX
Definition: Objects.h:104
dd4hep::xml::Handle_t::hasAttr
bool hasAttr(const XmlChar *t) const
Check for the existence of a named attribute.
Definition: XMLElements.cpp:676
dd4hep::Tube
Class describing a tube shape of a section of a tube.
Definition: Shapes.h:629
dd4hep::xml::createStdVolume
Volume createStdVolume(Detector &description, xml::Element element)
Create a simple volume using the shape plugin mechanism from the attributes of the XML element.
Definition: Utilities.cpp:100
dd4hep::isA< UnionSolid >
bool isA< UnionSolid >(const Handle< TGeoShape > &solid)
Definition: ShapeUtilities.cpp:171
dd4hep::Solid_type::dimensions
std::vector< double > dimensions()
Access the dimensions of the shape: inverse of the setDimensions member function.
Definition: Shapes.cpp:90
dd4hep::isInstance< PolyhedraRegular >
template bool isInstance< PolyhedraRegular >(const Handle< TGeoShape > &solid)
dd4hep::xml::Handle_t::attr
T attr(const Attribute a) const
Access typed attribute value by the XmlAttr.
Definition: XMLElements.h:454
Printout.h
POLYHEDRA_TAG
#define POLYHEDRA_TAG
Definition: ShapeTags.h:34
xml_dim_t
dd4hep::xml::Dimension xml_dim_t
Definition: XML.h:31
dd4hep::toStringMesh
std::string toStringMesh(const TGeoShape *shape, int precision=2)
Output mesh vertices to string.
Definition: ShapeUtilities.cpp:1295
Utilities.h
dd4hep::SubtractionSolid
Class describing boolean subtraction solid.
Definition: Shapes.h:1879
dd4hep::SensitiveDetector::setType
SensitiveDetector & setType(const std::string &typ)
Set detector type (structure, tracker, calorimeter, etc.).
Definition: DetElement.cpp:403
dd4hep::isInstance< PseudoTrap >
bool isInstance< PseudoTrap >(const Handle< TGeoShape > &solid)
Definition: ShapeUtilities.cpp:107
dd4hep::Paraboloid
Class describing a Paraboloid shape.
Definition: Shapes.h:1379
ELLIPTICALTUBE_TAG
#define ELLIPTICALTUBE_TAG
Definition: ShapeTags.h:28
dd4hep::isInstance< Trap >
template bool isInstance< Trap >(const Handle< TGeoShape > &solid)
dd4hep::xml::Handle_t::attr_nothrow
Attribute attr_nothrow(const XmlChar *tag) const
Access attribute pointer by the attribute's unicode name (no exception thrown if not present)
Definition: XMLElements.cpp:671