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